"""
/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
 """
import sys

from Analyzer import SClass, ExMethod, STypeDeclaration, SAnnotationType, ExField
from Analyzer import SCompilationUnit
from Analyzer import SField
from Analyzer import SGlobal
from Analyzer import SEnum
from Analyzer import SHelper
from Analyzer import SInterface
from Analyzer import SMethod
from Analyzer import SModifier
from Analyzer import SPackage
from Analyzer import STypeDeclaration
from Compiler import WAFCompileError
from JavaLangAST import Annotation
from JavaLangAST import AnnotationMethod
from JavaLangAST import AnnotationType
from JavaLangAST import ArrayInitializer
from JavaLangAST import Block
from JavaLangAST import Class
from JavaLangAST import ClassBody
from JavaLangAST import ClassCreatorRest
from JavaLangAST import ClassOrInterfaceType
from JavaLangAST import CompilationUnit
from JavaLangAST import Creator
from JavaLangAST import CreatorArray
from JavaLangAST import CreatorInner
from JavaLangAST import ElementValuePair
from JavaLangAST import Enum
from JavaLangAST import EnumBody
from JavaLangAST import EnumConstant
from JavaLangAST import ExArguments
from JavaLangAST import ExArray
from JavaLangAST import ExArrayIndex
from JavaLangAST import ExCastExpression
from JavaLangAST import ExClass
from JavaLangAST import ExCreator
from JavaLangAST import ExDot
from JavaLangAST import ExIdentifier
from JavaLangAST import ExInnerCreator
from JavaLangAST import ExLiteral
from JavaLangAST import ExOperator
from JavaLangAST import ExParExpression
from JavaLangAST import ExPart
from JavaLangAST import ExPrimary
from JavaLangAST import ExPrimitiveType
from JavaLangAST import ExSuper
from JavaLangAST import ExThis
from JavaLangAST import ExType
from JavaLangAST import ExTypeArguments
from JavaLangAST import ExVoid
from JavaLangAST import Expression
from JavaLangAST import Field
from JavaLangAST import Import
from JavaLangAST import InnerCreator
from JavaLangAST import Interface
from JavaLangAST import InterfaceField
from JavaLangAST import InterfaceMethod
from JavaLangAST import Literal
from JavaLangAST import LocalVariableDeclaration
from JavaLangAST import Method
from JavaLangAST import Modifier
from JavaLangAST import OprAdditive
from JavaLangAST import OprAssign
from JavaLangAST import OprBinary
from JavaLangAST import OprEquality
from JavaLangAST import OprInstanceOf
from JavaLangAST import OprLogical
from JavaLangAST import OprMultiplicative
from JavaLangAST import OprPostfix
from JavaLangAST import OprRelational
from JavaLangAST import OprShift
from JavaLangAST import OprTernary
from JavaLangAST import OprUnary
from JavaLangAST import Parameter
from JavaLangAST import PrimitiveType
from JavaLangAST import QualifiedName
from JavaLangAST import StaticBlock
from JavaLangAST import StmtAssert
from JavaLangAST import StmtBlock
from JavaLangAST import StmtBreak
from JavaLangAST import StmtCatch
from JavaLangAST import StmtContinue
from JavaLangAST import StmtDoWhile
from JavaLangAST import StmtExp
from JavaLangAST import StmtExplicitConstructorInvocation
from JavaLangAST import StmtFor
from JavaLangAST import StmtForEach
from JavaLangAST import StmtIf
from JavaLangAST import StmtLabel
from JavaLangAST import StmtLocalVariableDeclaration
from JavaLangAST import StmtReturn
from JavaLangAST import StmtSemicolon
from JavaLangAST import StmtSwitch
from JavaLangAST import StmtSwitchBlock
from JavaLangAST import StmtSynch
from JavaLangAST import StmtThrow
from JavaLangAST import StmtTry
from JavaLangAST import StmtWhile
from JavaLangAST import Type
from JavaLangAST import TypeArgument
from JavaLangAST import TypeParameter
from JavaLangAST import VariableDeclarator
import copy
import datetime
import os
from JSNI import processNativeCode
from Tokenizer import Token, TokenStream
from ConfigReader import WAFConfig
import UIControlCompiler
import hashlib
import SharedTypes
#from Java2js_SCS import SCS


"""
from JavaLangAST import Literal,Modifier,Annotation,ArrayInitializer,Block,Class,ClassBody,CompilationUnit,CreatorArray,Creator,CreatorInner
from JavaLangAST import QualifiedName,ElementValuePair,Field  ,Interface,Literal,LocalVariableDeclaration,Method,Modifier,OprAdditive,OprAssign,OprBinary,OprEquality,OprLogical,OprMultiplicative,OprPostfix,OprRelational,OprShift,OprTernary
from JavaLangAST import Import,OprUnary,Parameter,PrimitiveType,StmtBreak,StmtCatch,StmtContinue,StmtDoWhile,StmtFor,StmtIf,StmtLabel,StmtReturn,StmtSwitch,StmtSwitchBlock,StmtSynch,StmtThrow,StmtThrow,StmtTry,StmtWhile,Type,TypeArgument,TypeParameter,VariableDeclarator
from JavaLangAST import Expression,ExPart,ExParExpression,ExIdentifier,ExArrayIndex,ExArguments,ExCastExpression,ExLiteral,ExArray,ExTypeArguments,ExDot,ExThis,ExSuper,ExPrimitiveType
from JavaLangAST import ExClass,ExVoid,ExInnerCreator,InnerCreator,ClassCreatorRest,StmtExp,StmtBlock,ExOperator,ExType,OprInstanceOf,ClassOrInterfaceType,StmtLocalVariableDeclaration,StmtExplicitConstructorInvocation,InterfaceField,InterfaceMethod,StaticBlock,Enum,EnumBody,EnumConstant,ExCreator,StmtAssert,StmtSemicolon
from JavaLangAST import AnnotationType,AnnotationMethod
"""
class ExternCreate:
	count = 0
	instances = []
	md5s = {}
	def __init__(self):
		self.cid = ExternCreate.count
		ExternCreate.count += 1
		self.clazz = None
		self.from_controller = False		
	@staticmethod
	def getCode():		
		code = []		
		for i in ExternCreate.instances:
			mcode = []
			name = WAFConfig.getWAFRootObjectName() + "._cc.c" + str(i.cid) 
			fline = name + "=function(p,a)"
			count = 0
			dcode = []
			dcode.append("var o=a[0];")
			for m in i.clazz.methods:
				#arg += ",m" + str(count)
				if m == None:
					m = None
				dcode.append("o." + m.getJSName() + "=a[" + str(count + 1) + "];")				
				count += 1

			#mcode.append(line)
			#mcode.append("{")
			dcode.append("if(p!=null)o._pi=p;")
			cls = i.clazz
			acode = []
			
			has_implemented_method = False
			for m in cls.exmembers:
				if not isinstance(m, ExMethod):continue
				if m.method.isAbstract():continue
				if m.imid == None:continue
			
				#No need to add break since we are returning
				mapped = {}				
				for im in m.imid:			
					if mapped.has_key(im.method.mid):continue
					mapped[im.method.mid] = 1
					if WAFConfig.isMinify():
						line = "o." + "_" + str(im.method.mid) + " =o." + m.method.getJSName() + ";"
					else:
						line = "o." + im.method.getName() + "_" + str(im.method.mid) + " =o." + m.method.getJSName() + ";"
					acode.append(line)
				has_implemented_method = True
			if has_implemented_method == True:
				dcode.append("".join(acode))
			dcode.append("return o;")
			mcode.append(fline)
			mcode.append("{")
			mcode.append(dcode)		
			mcode.append("};")
			md5 = hashlib.sha256(getFormatedCode(dcode, 0)).hexdigest()
			if ExternCreate.md5s.has_key(md5):
				line = name + "=" + ExternCreate.md5s[md5] + ";"
				code.append(line)
			else:
				ExternCreate.md5s[md5] = name
				code.append(mcode)
			########		
			#######
			
		return code
	


def check_instance(ob, classes):
	for cls in classes:
		if isinstance(ob, cls):
			return True
	return False

def getSpaces(l):return " " * l
def getFormatedCode(code, l):	
	s = ""
	if not WAFConfig.isMinify():
		s = getSpaces(l)
	
	rcode = []
	if isinstance(code, list):
		for c in code:
			if isinstance(c, str):
				if "\n" in c:
					c = c.split("\n")
					rcode.append(getFormatedCode(c, (l + 4)))
				elif len(c.strip()) > 0:
					rcode.append(s + c)
				
			else:
				rcode.append(getFormatedCode(c, (l + 4)))
	else:
		rcode.append(code)	
	return "\n".join(rcode)

def  writeOnlyPackageInstanceCreation(root, names, code):
	
	mynames = []
	code.append
	if root.name != "":
		for n in names:mynames.append(n)
		mynames.append(root.name)
	line = ""
	if root.name != "":
		line = WAFConfig.getWAFRootObjectName() + "." + ".".join(mynames) + "={};"
		code.append(line)
	for p in root.subpackages:
		writeOnlyPackageInstanceCreation(root.subpackages[p], mynames, code)

def  writePackageInstanceCreation(root, names, code):
	
	mynames = []
	code.append
	if root.name != "":
		for n in names:mynames.append(n)
		mynames.append(root.name)
	"""
	line = ""
	if root.name != "":
		s = "_".join(names)
		if s == "":
			line = WAFConfig.getWAFRootObjectName() + "." + ".".join(mynames) + "={};"
		else:
			line = WAFConfig.getWAFRootObjectName() + "." + ".".join(mynames) + "={};"
	code.append(line)
	"""
	for name in root.types:
		fp=None
		t = root.types[name]		
		fp = t.prototype			
		line = None		
		if t.fullname == "java.lang.Object" or t.fullname == "com.openwaf.client.core.Client":continue
		if t.fullname=="java.lang.String":
			line = fp + "=String;"
			code.append(line)
		elif t.fullname=="com.openwaf.client.core.JsDate":
			line = fp + "=Date;"
			code.append(line)
		elif t.package == "com.openwaf.client.dom" and (t.fullname.endswith("Element") or t.name in ["Node", "Text", "Document", "Style", "NativeEvent"]):
			
			if WAFConfig.isCompatibleWithIE67() == False:
				if SGlobal.clientclass==None:					
					SGlobal.clientclass=SHelper.getClassOnFullName("com.openwaf.client.core.Client")
					if SGlobal.clientclass==None:
						raise Exception("Critical:class not found com.openwaf.client.core.Client")
				ie_feild=SGlobal.clientclass.getFieldWithThisAccess("IE", True, None).field
				firefox_feild=SGlobal.clientclass.getFieldWithThisAccess("FIREFOX", True, None).field
				if t.name == "NativeEvent":
					line = fp + "=Event;"
					code.append(line)			
				elif t.name == "Document":					
					code.append("if(" + SGlobal.clientclass.getPrototype() + ".$."+ie_feild.getJSName()+"){")
					line = fp + "=Document;"
					code.append(line)
					code.append("}else{")
					line = fp + "=HTMLDocument;"
					code.append(line)
					code.append("}")
				elif t.name == "Style":
					line = fp + "=CSSStyleDeclaration;"
					code.append(line)
				elif t.name in ["Node", "Text"]:
					line = fp + "=" + t.name + ";"
					code.append(line)
				elif t.name == "SpanElement":#TODO:Mozilla do have htmlspanelement
					line = fp + "=HTMLElement;"
					code.append(line)
				elif t.name == "ModElement":#TODO:Mozill 
					code.append("if(" + SGlobal.clientclass.getPrototype() + ".$."+firefox_feild.getJSName()+"){")
					line = fp + "=HTMLDelElement;"
					code.append(line)
					code.append("}else{")
					line = fp + "=HTMLModElement;"
					code.append(line)
					code.append("}")
				else:
					line = fp + "=HTML" + t.name + ";"
					code.append(line)
			else:
				line = fp + "=function(){};" 
				code.append(line)
		else:
			writePackageInstanceCreationForType(t, mynames, code)							
		writePackageInstanceCreationForInnerClassese(t, mynames, code)
		######

	for p in root.subpackages:
		writePackageInstanceCreation(root.subpackages[p], mynames, code)
def  writePackageInstanceCreationForInnerClassese(cls, names, code):
	if not(cls.innerMembers != None and len(cls.innerMembers) > 0):
		return
	mynames = []
	for n in names:mynames.append(n)
	mynames.append(cls.name)
	for im in cls.innerMembers:
		writePackageInstanceCreationForType(im, mynames, code)
		writePackageInstanceCreationForInnerClassese(im, mynames, code)


def writePackageInstanceCreationForType(t, names, code):	
	fp=t.prototype
	######	
	if t.isClass() or t.isEnum():
		line = fp + "=function(){"
		SA.currentClass = t
		sym = []
		sym.append({})
		sym[0][0] = {}
		#TODO:optimize
		for index in range(t.field_index):
			for f in t.fields:
				f = t.fields[f]
				if f.isStatic() == False and f.field_index == index:
					#TODO:sequence is important here
					if f.init == None:
						if SA.isBasicType(f.type):
							if SA.isBasicNumericType(f.type):
								line += "this." + f.getJSName() + "=0;"
							else:
								line += "this." + f.getJSName() + "=false;"
						else:
							line += "this." + f.getJSName() + "=null;"
						if WAFConfig.isMinify() == False:
							line += "\n";
					else:
						ecode = []
						t2 = SA.checkExpression(f.init, sym, 0, ecode)
						ecode = SA.getVariableInitializerCode(f.type, t2, ecode[0], f.init)
						line += "this." + f.getJSName() + "=" + ecode + ";"
						if WAFConfig.isMinify() == False:
							line += "\n";
		vfname = t.getCompilationUnit().filepath
		vfname = vfname[:-5] + ".view.html"
		if (not t.isInner()) and os.path.exists(vfname):
			line += "this.__iv();"
		line += "};"
		code.append(line)
	else:
		line = fp + "=function(){};"
		code.append(line)
	
	
	#########	
###############
###############
def  writePackageInstanceCreation_proto(root, names):
	mynames=[]
	if WAFConfig.isMinify()==False:		
		if root.name != "":
			for n in names:mynames.append(n)
			mynames.append(root.name)
	for name in root.types:
		t = root.types[name]
		writePackageInstanceCreationForType_proto(t,mynames)				
		writePackageInstanceCreationForInnerClasses_proto(t, mynames)	
	for p in root.subpackages:
		writePackageInstanceCreation_proto(root.subpackages[p], mynames)
def  writePackageInstanceCreationForInnerClasses_proto(cls, names):
	if not(cls.innerMembers != None and len(cls.innerMembers) > 0):
		return
	mynames = []
	for n in names:mynames.append(n)
	mynames.append(cls.name)
	for im in cls.innerMembers:
		writePackageInstanceCreationForType_proto(im, mynames)
		writePackageInstanceCreationForInnerClasses_proto(im, mynames)


def writePackageInstanceCreationForType_proto(t, names):	
	if WAFConfig.isMinify():
		sp = SHelper.getCharForNumber(t.clsid)
		sp = WAFConfig.getWAFRootObjectName() + "." + sp
		t.prototype = sp
	else:			
		fp = WAFConfig.getWAFRootObjectName() + "." + ".".join(names) + "." + t.name			
		t.prototype = fp
###############
###############



def writePackagePrototypeInstance(root):
	code = []
	writePackageInstanceCreation_proto(root, [])
	if not WAFConfig.isMinify():
		writeOnlyPackageInstanceCreation(root, [], code)
	return code
def writeTypePrototypeInstance(root):
	code = []
	writePackageInstanceCreation(root, [], code)
	return code
#####################33
######################
def writeClassInstanceCreation(root, line):
	code = []
	code.append("var cc=" + line + ";")
	writePackageClassInstanceCreation(root, [], code, line)
	return code
def  writePackageClassInstanceCreation(root, names, code, line):
	mynames = []
	code.append
	if root.name != "":
		for n in names:mynames.append(n)
		mynames.append(root.name)
	for name in root.types:
		t = root.types[name]		
		writeClassInstanceCreationForType(t, mynames, code, line)		
		writeClassInstanceCreationForInnerClassese(t, mynames, code, line)
	for p in root.subpackages:
		writePackageClassInstanceCreation(root.subpackages[p], mynames, code, line)
def writeClassInstanceCreationForInnerClassese(cls, names, code, line):
	if not(cls.innerMembers != None and len(cls.innerMembers) > 0):
		return
	mynames = []
	for n in names:mynames.append(n)
	mynames.append(cls.name)
	for im in cls.innerMembers:
		writeClassInstanceCreationForType(im, mynames, code, line)
		writeClassInstanceCreationForInnerClassese(im, mynames, code, line)
def writeClassInstanceCreationForType(t, names, code, line):
	if t.isAnnotationType() or t.isInterface() or t.isAbstract() or t.fullname.startswith("controllers."):		
		return	
	fp = t.getPrototype();
	name = ".".join(names) + "." + t.name
	line = "cc"
	code.append(fp + ".$._clz=" + line + "(\"" + name + "\");")
#######################3
###########################33




class SA:#Java script writer
	currentClass = None
	currentMethod = None
	collect_locals = False 
	collect_locals_limit = -1
	locals_bag = None
	
	@staticmethod
	def isWrapperClass(t):
		if t.coit == None:return False
		if t.coit.clazz == None:
			raise "UnExpected"
		if not isinstance(t.coit.clazz, STypeDeclaration):return False
		fname = t.coit.clazz.fullname
		if not fname.startswith("java.lang."):return False
		fname = fname[10:]
		if "." in fname: return False
		return fname in ["Number", "Byte", "Double", "Float", "Integer", "Long", "Short", "Boolean", "Character"]
	@staticmethod
	def canUnbox(t):
		if t.coit == None:return False
		if t.coit.clazz == None:
			raise "UnExpected"
		fname = t.coit.clazz.fullname
		if not fname.startswith("java.lang."):return False
		fname = fname[10:]
		if "." in fname: return False
		#Only change is 'Number' is excluded since it can not unboxed 
		return fname in ["Byte", "Double", "Float", "Integer", "Long", "Short", "Boolean", "Character"]
	
	
	
	@staticmethod
	def fromWrapperClassToBasic(t):
		if t.coit == None:raise "Unexpected"
		if t.coit.clazz == None:raise "UnExpected"
		fname = t.coit.clazz.fullname
		if not fname.startswith("java.lang."):raise "UnExpected"
		fname = fname[10:]
		if "." in fname: raise "UnExpected" 
		if not(fname in ["Number", "Byte", "Double", "Float", "Integer", "Long", "Short", "Boolean", "Character"]):raise "UnExpected"
		if fname == "Number":
			raise "Can not convert number to basic type"
		if fname == "Byte":return SGlobal.basictypes[PrimitiveType.BYTE]
		if fname == "Double":return SGlobal.basictypes[PrimitiveType.DOUBLE]
		if fname == "Float":return SGlobal.basictypes[PrimitiveType.FLOAT]
		if fname == "Integer":return SGlobal.basictypes[PrimitiveType.INT]
		if fname == "Long":return SGlobal.basictypes[PrimitiveType.LONG]
		if fname == "Short":return SGlobal.basictypes[PrimitiveType.SHORT]
		if fname == "Boolean":return SGlobal.basictypes[PrimitiveType.BOOLEAN]
		if fname == "Character":return SGlobal.basictypes[PrimitiveType.CHAR]
		raise "UnExpected"
	@staticmethod
	def fromBasicToWrapperClass(t):
		if t.pm_type == None: raise "UnExpected"
		v = t.pm_type.value
		SGlobal.initWarraperTypes()#TODO:move this somewhere as need to call only once
		return SGlobal.wrappertypes[v]
	@staticmethod
	def boxIt(t, code):
		v = t.pm_type.value		
		if SGlobal.autobxingclass==None:
			SGlobal.autobxingclass = SHelper.getClassOnFullName("com.openwaf.core.framework.Autoboxing")
			if SGlobal.autobxingclass==None:
				raise Exception("Critical:Can not not find class com.openwaf.core.framework.Autoboxing")
		ab=SGlobal.autobxingclass
		if v == PrimitiveType.BYTE:
			return ab.getPrototype() + ".$.bb(" + code + ")"
		if v == PrimitiveType.CHAR:
			return ab.getPrototype() + ".$.bc(" + code + ")"
		if v == PrimitiveType.SHORT:
			return ab.getPrototype() + ".$.bs(" + code + ")"
		if v == PrimitiveType.INT:
			return ab.getPrototype() + ".$.bi(" + code + ")"
		if v == PrimitiveType.LONG:
			return ab.getPrototype() + ".$.bl(" + code + ")"
		if v == PrimitiveType.FLOAT:
			return ab.getPrototype() + ".$.bf(" + code + ")"
		if v == PrimitiveType.DOUBLE:
			return ab.getPrototype() + ".$.bd(" + code + ")"
		if v == PrimitiveType.BOOLEAN:
			return ab.getPrototype() + ".$.bbl(" + code + ")"
		raise "UnExpected"
	@staticmethod
	def getClassForType(t):
		if t.coit != None:
			return t.coit.clazz
		if t.pm_type != None and t.pm_type.value == PrimitiveType.NULL:
			return SGlobal.objclass
		raise "UnExpected"
	@staticmethod
	def isStringType(t):
		if t.coit == None:return False
		if t.coit.clazz == None:raise "UnExpected"
		return t.coit.clazz.fullname == "java.lang.String"
	@staticmethod
	def isSingleDimentionBasicTypeArray(t):
		if t.coit == None: return False
		if t.coit.clazz == SGlobal.arrayclass:
			ne = t.coit.next
			if SA.isBasicType(ne) or SA.isStringType(ne):
				return True
		return False
	@staticmethod
	def isSharedType(t):    
		if t.coit != None and t.coit.clazz != None:
			if t.coit.clazz.getPackage().startswith("shared."):
				return True
		return False
	@staticmethod
	def isArrayOfSharedType(t):
		if t.coit != None and t.coit.clazz != None and t.coit.clazz == SGlobal.arrayclass:
			return SA.isSharedType(t.coit.next)
		return False
	@staticmethod
	def hasToString(t):
		raise "not implemented"		
	@staticmethod
	def isBasicType(t):
		if t.pm_type == None:
			return False
		if t.pm_type.value == PrimitiveType.NULL:
			return False
		return True
	@staticmethod
	def isBasicNumericType(t):
		if t.pm_type == None: return False
		return t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.DOUBLE, PrimitiveType.FLOAT, PrimitiveType.INT, PrimitiveType.LONG, PrimitiveType.SHORT]
	@staticmethod
	def canBeArrayIndex(t):
		if not isinstance(t, Type):return False
		if t.pm_type == None: return False
		return t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.SHORT]
	@staticmethod
	def collectTypes(scu, classes):
		for d in scu.delcs:
			if isinstance(d, STypeDeclaration):
				classes.append(d)
				d.collectTypes(classes)
			else:
				some_method()
	@staticmethod
	def checkType(cls, checking_controller=False):
		code = []
		sym = []
		sym.append({})
		sym[0][0] = {}
		#TODO:add all imports here
		
		if isinstance(cls, SClass):
			code += SA.checkSClass(cls, sym, 0, checking_controller)
		elif isinstance(cls, SInterface):
			code += SA.checkSInterface(cls, sym, 0)
		elif isinstance(cls, SEnum):
			code += SA.checkSClass(cls, sym, 0)
		elif isinstance(cls, SAnnotationType):
			pass
		else:			
			some_method()
		sym.pop()
		return code
	@staticmethod
	def checkCompilationUnit(scu):
		#scu=SCompilationUnit()
		code = []
		sym = []
		sym.append({})
		sym[0][0] = {}
		#TODO:add all imports here
		for d in scu.delcs:
			if isinstance(d, SClass):
				code += SA.checkSClass(d, sym, 0)
			elif isinstance(d, SInterface):
				code += SA.checkSInterface(d, sym, 0)
			elif isinstance(d, SEnum):
				code += SA.checkSClass(d, sym, 0)
			else:
				some_method()
		sym.pop()
		return code
	@staticmethod
	def checkSClass(cls, sym, i, checking_controller=False):
		code = []
		#if cls.fullname.startswith("com.openwaf.common.annotation.") or cls.fullname.startswith("java.lang.annotation"):
		#	return code 
		if checking_controller == False and cls.isControllerClass():
			return code
		SA.currentClass = cls
		sym.append({})		
		code.append("_p=" + cls.getPrototype() + ";")
		if len(cls.exclass) > 0:
			ex = cls.exclass[0]
			#if cls.fullname not in ["java.lang.String","com.openwaf.client.core.JsDate"]:
			if cls.fullname != "java.lang.String":
				if cls.package == "com.openwaf.client.dom":
					if cls.fullname.endswith("Element") or cls.name in ["Node", "Text", "Document", "Style", "NativeEvent"]:
						if WAFConfig.isCompatibleWithIE67():
							line = "_p.prototype=new " + ex.getPrototype() + ";"
							code.append(line)
							code.append("_p.$=_p.prototype;")
							code.append("_p=_p.$;")
							code.append("_p.constructor=" + cls.getPrototype() + ";")
						else:
							code.append("_p.$=_p.prototype;")
							code.append("_p=_p.$;") 
					else:
						line = "_p.prototype=new " + ex.getPrototype() + ";"
						code.append(line)
						code.append("_p.$=_p.prototype;")
						code.append("_p=_p.$;")
						code.append("_p.constructor=" + cls.getPrototype() + ";")
				else:
					line = "_p.prototype=new " + ex.getPrototype() + ";"
					code.append(line)
					code.append("_p.$=_p.prototype;")
					code.append("_p=_p.$;")
					code.append("_p.constructor=" + cls.getPrototype() + ";")
			else:
				code.append("_p.$=_p.prototype;")
				code.append("_p=_p.$;")
		else:
			code.append("_p.$=_p.prototype;")
			code.append("_p=_p.$;")
			
	
			
		instance_ids = []
		cls.getInstanceIds(instance_ids)
		line = "{"
		hash_ids = {}
		add_comma = False
		for mid in instance_ids:
			if hash_ids.has_key(mid):continue
			hash_ids[mid] = 1
			if add_comma == True:line += ","
			line += "'" + str(mid) + "':0"
			add_comma = True
		line += "};"
		code.append("_p._id=" + str(cls.clsid) + ";")
		code.append("_p._i=" + line)
		
		SA.checkMethods(cls, sym, i + 1, code)
		ui = SHelper.getClassOnFullName("com.openwaf.client.ui.UIControl")
		d = cls.getDegreeWithThis(ui)
		if d >= 0:
			fname = cls.getCompilationUnit().filepath
			fname = fname[:-5] + ".view.html"
			if (not cls.isInner()) and  os.path.exists(fname):
				oc_code = UIControlCompiler.processControl(fname, cls)
				dcode = []
				dcode.append("_p.__iv=function(){")
				dcode.append(oc_code)
				dcode.append("}")
				code.append(dcode)
		
		
		if cls.isAbstract() == False:
			acode = []
			for m in cls.exmembers:
				if not isinstance(m, ExMethod):continue				
				if m.method.isAbstract():continue
				if m.imid == None:continue				
				c = m.method
				if WAFConfig.isRemoveUnusedCode() and (c.mid not in SGlobal.used_methods):
					found = False
					for im in c.imid:
						if im.mid in SGlobal.used_methods:
							found = True
							break
					if found == False:continue
				line = "";
				mapped = {}				
				for im in m.imid:			
					if mapped.has_key(im.method.mid):continue
					mapped[im.method.mid] = 1
					iname=None
					if WAFConfig.isMinify():
						iname = "_" + str(im.method.mid)
					else:
						iname = im.method.getName() + "_" + str(im.method.mid)
					if cls.symbols.has_key(iname):continue
					cls.symbols[iname]=1
					if WAFConfig.isMinify():
						line = "_p." + "_" + str(im.method.mid) + " =_p." + m.method.getJSName() + ";"
					else:															
						line = "_p." + im.method.getName() + "_" + str(im.method.mid) + " =_p." + m.method.getJSName() + ";"
					acode.append(line)
				#No need to add break since we are returning								
				#has_implemented_method = True
			code.append(acode)		
		
		if cls.hasStaticBlocks():
			if cls.hasStaticStaticBlocks():
				sbname = cls.getFullSymbolToUse("_sb")
				static_code = []
				static_code.append("_p." + sbname + "=function(){")
				for b in cls.static_blocks:
					block_code = []
					SA.checkBlock(b, sym, i + 1, block_code)
					static_code.append(block_code)			
				static_code.append("}")
				SGlobal.addStaticCodeCall(cls.getPrototype() + ".$." + sbname + "();")
				code.append(static_code)
			if cls.hasInstanceStaticBlocks():
				sbname = cls.getFullSymbolToUse("_isb")
				sbe_marker = cls.getFullSymbolToUse("_isbc")
				static_code = []
				static_code.append("_p." + sbname + "=function(){")
				static_code.append("if(this." + sbe_marker + " && this." + sbe_marker + "==true) return;")
				static_code.append("this." + sbe_marker + "=true;")
				for b in cls.instance_static_blocks:
					block_code = []
					SA.checkBlock(b, sym, i + 1, block_code)
					static_code.append(block_code)			
				static_code.append("}")
				cls.static_code_function_name = sbname
				code.append(static_code)
		SA.checkConstructors(cls, sym, i + 1, code)
		_static_field_access_added = False
		if SGlobal.necessory_classes_processed == True  and cls.fullname == "com.openwaf.client.core.Client":
			sym.pop()
			return code
		for f in cls.fields:
			f = cls.fields[f]
			if f.isStatic():
				if _static_field_access_added == False:
					line = "_p=" + cls.getPrototype() + ".$;"
					SGlobal.addStaticFieldLine(line)
					_static_field_access_added = True
				if f.init == None:
					if SA.isBasicType(f.type):
						if SA.isBasicNumericType(f.type):
							SGlobal.addStaticFieldLine("_p." + f.getJSName() + "=0;")
						else:
							SGlobal.addStaticFieldLine("_p." + f.getJSName() + "=false;")
					else:
						SGlobal.addStaticFieldLine("_p." + f.getJSName() + "=null;")
				else:
					line = "_p." + f.getJSName() + "="
					if isinstance(f.init, Expression):
						ecode = []
						t2 = SA.checkExpression(f.init, sym, i, ecode)
						if isinstance(t2, STypeDeclaration):
							t2 = SA.checkExpression(f.init, sym, i, ecode)
						ecode = SA.getVariableInitializerCode(f.type, t2, ecode[0], f.init)
						line += ecode + ";"
						SGlobal.addStaticFieldLine(line)
					elif isinstance(f.init, ArrayInitializer):
						ecode = []
						SA.checkArrayInitializer(f.init, sym, i, ecode)
						line += ecode[0] + ";"
						SGlobal.addStaticFieldLine(line)
						#raise  WAFCompileError("Array initializer not handled in static variable")
					else:						
						raise WAFCompileError("");
		
		sym.pop()
		return code

	@staticmethod
	def checkSInterface(cls, sym, i):
		code = []
		#if cls.fullname.startswith("waf.common.annotation.") or cls.fullname.startswith("java.lang.annotation"):
		#	return code
		SA.currentClass = cls
		sym.append({})

		#SA.collectSymbols(cls, sym, i + 1, 0)		
		code.append("_p=" + cls.getPrototype() + ";")
		code.append("_p.$=_p.prototype;")			
		code.append("_p._id=" + str(cls.clsid) + ";")
		_static_field_access_added = False
		for f in cls.fields:
			f = cls.fields[f]
			if f.isStatic():
				if _static_field_access_added == False:
					line = "_p=" + cls.getPrototype() + ".$;"
					SGlobal.addStaticFieldLine(line)
					_static_field_access_added = True
				if f.init == None:
					if SA.isBasicType(f.type):
						if SA.isBasicNumericType(f.type):
							code.append("_p." + f.getJSName() + "=0;")
						else:
							code.append("_p." + f.getJSName() + "=false;")
					else:
						code.append("_p." + f.getJSName() + "=null;")
				else:
					line = "_p." + f.getJSName() + "="
					if isinstance(f.init, Expression):
						ecode = []
						t2 = SA.checkExpression(f.init, sym, i, ecode)
						ecode = SA.getVariableInitializerCode(f.type, t2, ecode[0], f.init)
						
						line += ecode + ";"
						SGlobal.addStaticFieldLine(line)
					elif isinstance(f.init, ArrayInitializer):
						ecode = []
						SA.checkArrayInitializer(f.init, sym, i, ecode)
						line += ecode[0] + ";"
						SGlobal.addStaticFieldLine(line)
					else:
						raise  WAFCompileError("Criticle")
		if cls.hasStaticBlocks():
			static_code = []
			static_code.append("_p._static_code=function(){")
			for b in cls.static_blocks:
				block_code = []
				SA.checkBlock(b, sym, i + 1, block_code)
				static_code.append(block_code)			
			static_code.append("}")
			SGlobal.addStaticCodeCall(cls.getPrototype() + ".$._static_code();")
			code.append(static_code)
		sym.pop()
		return code
	@staticmethod
	def checkConstructors(cls, sym, i, jcode):		
		import Java2js_SCS
		code = []
		for c in cls.constructors:
			if WAFConfig.isRemoveUnusedCode():
				if not (cls.isEnum() or cls.fullname == "java.lang.Object" or cls.fullname == "java.lang.Enum"):
					if c.mid not in SGlobal.used_methods:continue
			if c.rettype != None:
				raise WAFCompileError(1003, c.name)
			SA.checkConstructorDuplication(c, cls)
			name = "_p." + c.getJSName() + "="
			ccode = []
			if c.callsModel():				
				Java2js_SCS.SCS.rc_counter = 0
				Java2js_SCS.SCS.checkConstructor(c, cls, sym, i, ccode)
			else:
				SA.checkConstructor(c, cls, sym, i, ccode)
			ccode[0] = name + ccode[0]
			#ccode.append(";")
			code.append(ccode)			
		jcode.append(code)
	@staticmethod
	def checkMethods(cls, sym, i, jcode):
		import Java2js_SCS
		code = []
		for c in cls.methods:
			if WAFConfig.isRemoveUnusedCode() and (c.mid not in SGlobal.used_methods):				
				if c.imid == None:continue
				found = False
				for im in c.imid:
					if im.mid in SGlobal.used_methods:
						found = True
						break
				if found == False:continue
			ccode = []
			name = ""
			name = "_p." + c.getJSName() + "="			
			if c.callsModel():				
				Java2js_SCS.SCS.rc_counter = 0
				Java2js_SCS.SCS.checkMethod(c, cls, sym, i, ccode)
			else:
				if cls.isModelClass():
					if not c.isPublic():continue					
					Java2js_SCS.SCS.checkMethod_Model(c, cls, ccode)
					ccode[0] = name + ccode[0]
					code.append(ccode)
					name = "_p.gd_" + str(c.mid) + "="
					ccode = []
					Java2js_SCS.SCS.checkMethod_Model_gd(c, cls, ccode)
					ccode[0] = name + ccode[0]
					code.append(ccode)
				else:
					if cls.getPackage().startswith("shared.") and (c.name == "toJSON" or c.name == "fromJSON"):
						if c.name == "toJSON":
							ccode = SharedTypes.ST.getJS_toJSONCode(cls)							
						else:
							ccode = SharedTypes.ST.getJS_fromJSONCode(cls)							
					else:
						SA.checkMethod(c, cls, sym, i, ccode)
			if len(ccode) > 0 and (not cls.isModelClass()):
				ccode[0] = name + ccode[0]
				#ccode.append(";")
				code.append(ccode)						
			#TODO:check this it should have @NoJavaScript annotation
				
		jcode.append(code)
	@staticmethod
	def getNextLocalSymbol(sym, s):
		c = len(sym[0][0])
		name = s + str(c)
		while sym[0][0].has_key(name):
			c += 1
			name = s + str(c)
		return name
	@staticmethod
	def checkMethod(c, cls, sym, i, jcode):
		m = c.method
		if c.getAnnotation("NoJavaScript") != None:			
			return
		if m.block == None and c.native_code == None:
			if c.isAbstract():return
			raise Exception("Method " + cls.fullname + "::" + c.name + " does not contain method definition or native code")
			#print "Method "+cls.fullname+"::"+c.name+" does not contain method definition or native code"
			#return
		outer_method = SA.currentMethod
		SA.currentMethod = c
		sym.append({})
		i = i + 1
		line = "function("
		count = 0
		for p in c.pars:
			SHelper.processType(p.typ, SA.currentClass, SA.currentMethod)
			if count > 0:line += ","
			count += 1
			
			sym[i][p.name.data] = p
			if m.block != None and WAFConfig.isMinify():
				name = SA.getNextLocalSymbol(sym, "p")
				p.js_name = name
				sym[0][0][name] = 1
				line += name
			else:
				sym[0][0][p.name.data] = 1
				p.js_name = p.name.data
				line += p.name.data
		line += ")"


		if m.block != None:
			jcode.append(line)
			jcode.append("{")
			#jcode.append("document.write('"+cls.fullname+"."+c.name+"<br/>');")
			code = []			
			SA.checkBlockStatements(m.block, sym, i, code)
			"""
			fcode=getFormatedCode(code,0)
			md5=hashlib.sha224(fcode).hexdigest()
			if SGlobal.hashes.has_key(md5):
				SGlobal.hashes[md5]+=1
				SGlobal.chars_saved+=len(fcode)
			else:
				SGlobal.hashes[md5]=1
			"""
			jcode.append(code)
			jcode.append("}")
		else:
			if c.native_code != None:				
				jcode.append(line)
				toks = processNativeCode(c.native_code)
				ncode = SA.checkNativeCode(toks)
				jcode.append(ncode)
			else:
				some_method()#TODO:remove when this happens
				jcode.append(line)
		sym.pop()
		SA.currentMethod = outer_method
	@staticmethod
	def checkNativeCode(toks):
		from JSNI import NTypeField, NTypeName, NArgType, NDot
		code = []
		skip_next_token = False
		add_comma_if_next_is_not_bracket = False
		for ct in toks:
			if isinstance(ct, Token):
				if WAFConfig.isMinify()and(ct.data.startswith("//") or ct.data.startswith("/*")):
					continue
				if skip_next_token == True:
					skip_next_token = False
					continue
				if add_comma_if_next_is_not_bracket == True:
					if ct.data != ")":
						code.append(",")
					add_comma_if_next_is_not_bracket = False
				code.append(ct.data)
			elif isinstance(ct, list):
				nei = 0
				t_nei = len(ct)
				accessing_static = True
				if isinstance(ct[0], NDot):
					nei = 1
					accessing_static = False
				if not isinstance(ct[nei], NTypeName):some_method()
				s = []
				for n in ct[nei].names:
					s.append(n.data)
				name = ".".join(s)
				inner_class_name = None
				accessing_inner_class = False
				outer_class = None
				base_class = None
				if "$" in name:
					[name, sep, inner_class_name] = name.rpartition("$")
					outer_class = SHelper.getClassOnFullName(name)
					if outer_class == None:
						print "Class not found in native code name ", name
						some_method()
					accessing_inner_class = True						
					base_class = outer_class.getInnerMember(inner_class_name)
					if base_class == None:
						print "Inner class not found to " + name + " with name " + inner_class_name + " in native code "
						some_method()
				else:
					base_class = SHelper.getClassOnFullName(name)
					if base_class == None:
						print "Class not found in native code", name
						some_method()

				nei += 1
				f = ct[nei]
				if not isinstance(f, NTypeField):some_method()
				nei += 1
				fname = f.name.data
				if t_nei == nei:
					if accessing_static == True:
						code.append(base_class.getPrototype() + ".$")
					f = base_class.getFieldWithThisAccess(fname, accessing_static, SA.currentClass)
					if f != None:
						if f.field.isStatic() == True and accessing_static == False:
							print "Can not access static member " + fname + " " + base_class.getFullname()
							some_method()
						code.append("." + f.field.getJSName())
					else:
						if accessing_static == False:
							f = base_class.getFieldFromContainerClass(fname, accessing_static, SA.currentClass)
							if f == None:
								print "Data member not found in native code " + fname + " " + base_class.getFullname()
								some_method()
							d = base_class.getDepthRelativeToThis(f.field.clazz)
							code.append(("._pi" * d) + "." + f.field.getJSName());
						else:
							print "Field not found in native code for static access " + fname + " for class " + base_class.getFullname()
							some_method()
				else:
					nt = ct[nei]
					if not isinstance(nt, list):
						print "non list", some_method()
					types = []
					for ta in nt:
						s = []
						for n in ta.names:
							s.append(n.data)
						name = ".".join(s)
						if len(name) > 1:	
							name = name[1:]#remove L
							arg_class = SHelper.getClassOnFullName(name)
							if arg_class == None:
								print "arg type not found", name
								some_method()
							#print name
							types.append(arg_class.mytype)
						else:
							if name == "I":
								types.append(SGlobal.basictypes[PrimitiveType.INT])
							else:
								print "not handled ", name
								some_method()
					if fname == "new":
						if accessing_inner_class == True:
							
							cons = base_class.getConstructor(types, SA.currentClass)
							if cons == None:
								print "matcing constructor not found in native code for " + base_class.getFullname()
								some_method()
							if accessing_static == True and base_class.isStatic() == False:
								print "Inner class (not static) can not instianated without outer class instance " + base_class.getFullname()
								some_method()
							if accessing_static == True:
								#if cons.isDefaultConstructor():
								#	code.append("new "+base_class.getPrototype+"(")
								#else:
								code.append("(new " + base_class.getPrototype + "())." + cons.getJSName() + "(")
							else:
								if isinstance(cons, str) or cons == None:
									line = "new " + base_class.getPrototype() + "()"
									code.append("._ic(" + line + ")")
									skip_next_token = True
								else:
									line = "._ic(new " + base_class.getPrototype() + "())." + cons.getJSName() + "("
									code.append(line) 
						else:
							cons = base_class.getConstructor(types, SA.currentClass)
							if cons == None:
								print "matcing constructor not found in native code for " + base_class.getFullname()
								cons = base_class.getConstructor(types, SA.currentClass)
								some_method()
							#if cons.isDefaultConstructor():
							#	line = "new " + base_class.getPrototype() + "("
							#	code.append(line)
							#else:
							line = "(new " + base_class.getPrototype() + "())." + cons.getJSName() + "("
							code.append(line) 
					else:
						###### FOR IE 6 native
						if base_class.package == "com.openwaf.client.dom" and WAFConfig.isCompatibleWithIE67():
							if base_class != SA.currentClass:
								print "Problem", some_method()														
							m = base_class.getMethodWithThisAccess(fname, types, accessing_static, None, SA.currentClass)
							
							if m.method.method.block == None and m.method.method.native_code == None:
								#can not minify this
								code.append(m.method.getJSName() + "(")													
							else:
								cl = len(code) - 1
								if cl >= 0 and len(code[cl]) > 0 and code[cl][-1] == ".":code[cl] = code[cl][:-1]
								line = None								
								line = base_class.getPrototype() + ".$." + m.method.getJSName() + ".call("
								add_comma_if_next_is_not_bracket = True
								if len(code[cl]) > 0:
									code[cl] = code[cl][0:-1] + line + code[cl][-1:]
								else:
									code[cl] = line + code[cl]
						###### FOR IE 6 native						
						else:
							m = base_class.getMethodWithThisAccess(fname, types, accessing_static, None, SA.currentClass)
							if m != None:
								if accessing_static == False:
									if m.method.isAbstract():
										#add_comma_if_next_is_not_bracket = True
										if WAFConfig.isMinify() == False:
											code.append("." + m.method.getName() + "_" + str(m.method.mid) + "(")
										else:
											code.append("._" + str(m.method.mid) + "(")
									else:
										code.append("." + m.method.getJSName() + "(")
								else:
									if m.method.isAbstract():
										print "Can not access abstract method statically Name:" + fname + "(" + base_class.getFullname() + ")"
										some_method() 
									code.append(base_class.getPrototype() + ".$")
									code.append("." + m.method.getJSName() + "(")
							else:
								if accessing_static == False:
									m = base_class.getMethodFromContainerClass(fname, types, accessing_static, SA.currentClass)
									if m == None:
										print "Method not found in native code " + fname + " " + base_class.getFullname()
										some_method()
									d = base_class.getDepthRelativeToThis(m.method.clazz)
									code.append(("._pi" * d) + "." + m.method.getJSName() + "(");
								else:
									print "Method not found in native code " + fname + " " + base_class.getFullname()
									some_method()
							
						
					
					
						
			else:				
				some_method()
				
		return "".join(code).split("\n")
		
		
	@staticmethod
	def checkConstructor(c, cls, sym, i, jcode):
		outer_method = SA.currentMethod
		SA.currentMethod = c
		m = c.method
		eci = None
		if m != None:
			eci = m.explconinv
		#TODO: check parameter declaration
		#TODO: find matching super class constructor
		sym.append({})
		i = i + 1

		line = "function("
		count = 0
		for p in c.pars:
			if count > 0:line += ","
			count += 1
			
			#SHelper.processType(p.typ,SA.currentClass)
			sym[i][p.name.data] = p
			if WAFConfig.isMinify():
				name = SA.getNextLocalSymbol(sym, "p")
				p.js_name = name
				sym[0][0][name] = 1
				line += name
			else:
				line += p.name.data
				sym[0][0][p.name.data] = 1
				p.js_name = p.name.data
		line += ")"
		#TODO:J handle constructor calling logic
		jcode.append(line)
		jcode.append("{")
		code = []
		if eci != None:
			if eci.is_super == True:
				if (cls.exclass == None or len(cls.exclass) == 0) and eci != None:
					raise WAFCompileError(1006, cls.name)
				ex = cls.exclass[0]
				acode = []
				cc = ex.getConstructor(SA.getExpressionListToTypeList(eci.arguments, sym, i, acode), SA.currentClass)
				if cc == None:
					raise WAFCompileError("Super Constructor not found", None)
				line = "this." + cc.getJSName() + "(" + ",".join(acode) + ");"
				code.append(line)
			elif eci.is_this == True:
				acode = []
				cc = cls.getConstructor(SA.getExpressionListToTypeList(eci.arguments, sym, i, acode), SA.currentClass)
				if cc == None:
					raise WAFCompileError("Super Constructor not found", None)
				line = "this." + cc.getJSName() + "(" + ",".join(acode) + ");"
				code.append(line)
			else:				
				print some_method()
		else:
			if cls.exclass != None and len(cls.exclass) == 1:#calling default constructor automatically
				ex = cls.exclass[0]
				
				if cls.isClass() and cls.fullname != "java.lang.String":
					cons = ex.getConstructor([], SA.currentClass)
					if cons == None:
						if len(ex.constructors) > 0:
							raise WAFCompileError(1005, ex.fullname)
					else:
						line = "this." + cons.getJSName() + "();"
						code.append(line)
				elif cls.isEnum():
					args = [SGlobal.stringclass.mytype, SGlobal.basictypes[Literal.INT]]
					cons = ex.getConstructor(args, SA.currentClass)
					v1 = SA.getVariable("_n", sym, i)
					v2 = SA.getVariable("_i", sym, i)
					line = "this." + cons.getJSName() + "(" + v1.getJSName() + "," + v2.getJSName() + ");"
					code.append(line)
				#else:
				#	some_method()
					
					
				
		if cls.hasInstanceStaticBlocks():
			code.append("this." + cls.static_code_function_name + "();")
		if m != None:
			for s in m.stmts:
				SA.checkStmt(s, sym, i, code)
		if cls.fullname != "java.lang.String":
			code.append("return this;")
		else:
			code[0] = "return " + code[0]
		jcode.append(code)			
		jcode.append("}")
		sym.pop()
		SA.currentMethod = outer_method
	@staticmethod
	def checkConstructorDuplication(c, cls):
		for m in cls.constructors:
			if c == m:continue
			if c.matchPars(m.pars):
				raise WAFCompileError(1004, c.name)

	


	@staticmethod
	def checkStmt(st, sym, i, jcode):
		if check_instance(st, [StmtForEach, StmtLocalVariableDeclaration, StmtAssert, StmtBlock, StmtBreak, StmtIf, StmtFor, StmtWhile, StmtDoWhile, StmtSwitch, StmtReturn, StmtThrow, StmtContinue, StmtTry, StmtExp]):
			if isinstance(st, StmtAssert): 	return SA.checkStmtAssert(st, sym, i, jcode)
			if isinstance(st, StmtBlock):  	return SA.checkBlock(st, sym, i, jcode)
			if isinstance(st, StmtBreak):  	return SA.checkStmtBreak(st, sym, i, jcode)
			if isinstance(st, StmtContinue):	   return SA.checkStmtContinue(st, sym, i, jcode)

			if isinstance(st, StmtFor):		return SA.checkStmtFor(st, sym, i, jcode)
			if isinstance(st, StmtIf):	 	return SA.checkStmtIf(st, sym, i, jcode)
			if isinstance(st, StmtLocalVariableDeclaration):	   return SA.checkStmtLocalVariableDeclaration(st, sym, i, jcode)
			if isinstance(st, StmtReturn): 	return SA.checkStmtReturn(st, sym, i, jcode)
			if isinstance(st, StmtSwitch): 	return SA.checkStmtSwitch(st, sym, i, jcode)
			if isinstance(st, StmtThrow):  	return SA.checkStmtThrow(st, sym, i, jcode)
			if isinstance(st, StmtTry):		return SA.checkStmtTry(st, sym, i, jcode)
			if isinstance(st, StmtWhile):  	return SA.checkStmtWhile(st, sym, i, jcode)
			if isinstance(st, StmtDoWhile):	return SA.checkStmtDoWhile(st, sym, i, jcode)
			if isinstance(st, StmtExp):	return SA.checkStmtExp(st, sym, i, jcode)
			if isinstance(st, StmtForEach): return SA.checkStmtForEach(st, sym, i, jcode)
			print "Unexpected ", SA.ttos(st)
			some_method()
		else:
			print "KKK", SA.ttos(st)
			some_method()
	@staticmethod
	def checkStmtAssert(st, sym, i, jcode):
		acode = []
		SA.checkExpression(st.exp1, sym, i, acode)
		jcode.append("if(!" + acode[0] + "){")
		if st.exp2 != None:
			ecode = []
			SA.checkExpression(st.exp2, sym, i, ecode)
			jcode.append(["throw " + ecode[0] + ";"])
		else:
			jcode.append(["throw AssertionError"])
		jcode.append("}")
			
		#TODO:
		return None
		#TODO:

	@staticmethod
	def checkStmtBlock(st, sym, i, jcode):#complete
		#TODO:to update index
		return SA.checkBlock(st.block, sym, i, jcode)

	@staticmethod
	def checkStmtBreak(st, sym, i, jcode):#complete
		jcode.append("break;")

	@staticmethod
	def checkStmtContinue(st, sym, i, jcode):#complete
		jcode.append("continue;")

	@staticmethod
	def checkStmtIf(st, sym, i, jcode):#complete
		code = []
		SA.checkParExpression(st.par, sym, i, code)
		jcode.append("if" + code[0])
		SA.checkStmt(st.stmt_if, sym, i, jcode)
		if st.stmt_else != None:
			jcode.append("else")
			SA.checkStmt(st.stmt_else, sym, i, jcode)

	@staticmethod
	def checkStmtFor(st, sym, i, jcode):#complete
		sym.append({})
		line = "for("
		if st.init != None:
			code = []
			SA.checkForInit(st.init, sym, i + 1, code)
			line += code[0]
		line += ";"
		if st.cond != None:
			code = []
			SA.checkExpression(st.cond, sym, i + 1, code)
			line += code[0]
		line += ";"
		code = []
		SA.checkExpressionList(st.exps, sym, i + 1, code)
		if len(code) > 0:
			line += code[0]
		line += ")"
		jcode.append(line)
		SA.checkStmt(st.stmt, sym, i + 1, jcode)
		sym.pop()
		
	

	@staticmethod
	def checkStmtForEach(st, sym, i, jcode):
		#TODO:check this type is not processed
		#TODO:J
		sym.append({})
		dcode = []
		SA.checkLocalVariableDeclaration(st.vd, sym, i + 1, dcode)
		code = []
		t = SA.checkExpression(st.exps, sym, i + 1, code)
		if t.isArray():
			vname = SA.getNextLocalSymbol(sym, "i")
			sym[0][0][vname] = 1
			aname = SA.getNextLocalSymbol(sym, "i")
			sym[0][0][aname] = 1
			#TODO:extra block is generated here lets have this for time being need to add only if necessory
			jcode.append("for(var " + vname + "=0," + aname + "=" + code[0] + ";" + vname + "<" + aname + ".length;" + vname + "++){/* for each */")
			jcode.append(dcode[0] + "=" + aname + "[" + vname + "];")
			SA.checkStmt(st.stmt, sym, i + 1, jcode)
			jcode.append("}")
			sym.pop()
		elif t.isIterable():
			#name=SA.getNextLocalSymbol(sym, i)
			vname = SA.getNextLocalSymbol(sym, "i")
			sym[0][0][vname] = 1
			iterable = SHelper.getClassOnFullName("java.lang.Iterable").mytype
			m = iterable.getMethodWithThisAccess("iterator", [], False, None, SA.currentClass)
			if WAFConfig.isMinify():
				code[0] += "." + "_" + str(m.method.mid) + "()"
			else:
				code[0] += "." +m.method.name +"_" + str(m.method.mid) + "()"
			iterator = SHelper.getClassOnFullName("java.util.Iterator").mytype
			m = iterator.getMethodWithThisAccess("hasNext", [], False, None, SA.currentClass)
			nm_line=None
			if WAFConfig.isMinify():
				nm_line = "." + "_" + str(m.method.mid) + "()"
			else:
				nm_line = "." +m.method.name +"_" + str(m.method.mid) + "()"
			jcode.append("for(var " + vname + "=" + code[0] + ";" + vname + nm_line + ";){/* for each */")
			nm = iterator.getMethodWithThisAccess("next", [], False, None, SA.currentClass)
			if WAFConfig.isMinify():
				nm_line = "." +  "_" + str(nm.method.mid) + "()"
			else:
				nm_line = "." +nm.method.name  +"_" + str(nm.method.mid) + "()"
			jcode.append(dcode[0] + "=" + vname + nm_line)
			SA.checkStmt(st.stmt, sym, i + 1, jcode)
			jcode.append("}")
			sym.pop()
		else:
			raise "UnExpected:Expected array of iterable in foreach loop"


	@staticmethod
	def checkForInit(st, sym, i, jcode):#complete
		if isinstance(st, LocalVariableDeclaration):
			return SA.checkLocalVariableDeclaration(st, sym, i, jcode)
		return SA.checkExpressionList(st, sym, i, jcode)

	@staticmethod
	def checkExpressionList(el, sym, i, jcode):#complete
		if len(jcode) == 0:jcode.append("")
		if el == None:return
		if not isinstance(el, list):
			print "Expecting list in CheckExpressionList"
			raise WAFCompileError(None, None)
		tcode = []
		for e in el:
			code = []
			SA.checkExpression(e, sym, i, code)
			tcode.append(code[0])
		jcode[0] += ",".join(tcode)

	@staticmethod
	def checkStmtLocalVariableDeclaration(st, sym, i, jcode):
		code = []
		r = SA.checkLocalVariableDeclaration(st.lvd, sym, i, code)
		jcode.append(code[0] + ";")
		return r
	@staticmethod
	def checkStmtWhile(st, sym, i, jcode):#complete
		line = "while"
		code = []
		SA.checkParExpression(st.par, sym, i, code)
		line += code[0]
		jcode.append(line)
		SA.checkStmt(st.stmt, sym, i, jcode)

	@staticmethod
	def checkStmtDoWhile(st, sym, i, jcode):#complete
		jcode.append("do")
		SA.checkStmt(st.stmt, sym, i, jcode)
		line = "while"
		code = []
		SA.checkParExpression(st.par, sym, i, code)
		line += code[0]
		jcode.append(line)

	@staticmethod
	def checkStmtSwitch(st, sym, i, jcode):#complete
		#TODO:J
		
		line = "switch"
		code = []
		is_enum = False
		t = SA.checkParExpression(st.par, sym, i, code)
		if t.coit != None and t.coit.clazz != None:
				if isinstance(t.coit.clazz, SEnum):
					is_enum = True
		if is_enum == True:
			line += code[0][:-1] + ".ordinal)"
		else:	
			line += code[0]
		jcode.append(line)
		jcode.append("{")
		code = []
		for b in st.cases:
			SA.checkSwitchBlock(b, sym, i, code, t)
		jcode.append(code)
		jcode.append("}")

	@staticmethod
	def checkSwitchBlock(sb, sym, i, jcode, t):#complete

		if sb.default == False:
			########
			#TODO:this can be optimized
			sym.append({})
			cls = None
			is_enum = False
			if t.coit != None and t.coit.clazz != None:
				if isinstance(t.coit.clazz, SEnum):
					cls = t.coit.clazz;
					is_enum = True	
					for name in cls.constants_hash:
						sym[i + 1][name] = cls
			
			#########
			code = []
			SA.checkExpression(sb.exp, sym, i + 1, code)
			if is_enum:
				jcode.append("case " + t.coit.clazz.getPrototype() + ".$." + code[0] + ".ordinal:")
			else:
				jcode.append("case " + code[0] + ":")
			sym.pop()
		else:
			jcode.append("default:")
		for st in sb.stmts:
			SA.checkBlockStatement(st, sym, i, jcode)

	@staticmethod
	def checkStmtReturn(st, sym, i, jcode):#complete
		if st.exp != None:
			code = []
			t = SA.checkExpression(st.exp, sym, i, code)
			code[0] = SA.applyJSTypeCast(t, SA.currentMethod.rettype, code[0])
			jcode.append("return " + code[0] + ";")

		else:
			jcode.append("return;")

	@staticmethod
	def checkStmtThrow(st, sym, i, jcode):#complete
		code = []
		SA.checkExpression(st.exp, sym, i, code)
		jcode.append("throw " + code[0] + ";")#TODO:J Revist this in exception handling

	@staticmethod
	def checkBlock(b, sym, i, jcode):#complete
		sym.append({})
		jcode.append("{")
		code = []
		SA.checkBlockStatements(b.block, sym, i + 1, code)
		jcode.append(code)
		jcode.append("}")
		sym.pop()

	@staticmethod
	def checkBlockStatements(sts, sym, i, jcode):#complete
		for st in sts:
			SA.checkBlockStatement(st, sym, i, jcode)

	@staticmethod
	def checkBlockStatement(st, sym, i, jcode):#complete
		#TODO:check this
		if isinstance(st, LocalVariableDeclaration):
			return SA.checkLocalVariableDeclaration(st, sym, i, jcode)
		if check_instance(st, [Class, Enum]):
			#TODO:update this
			return ""
		SA.checkStmt(st, sym, i, jcode)


	@staticmethod
	def checkStmtTry(st, sym, i, jcode):#inomplete
		#TODO:J
		jcode.append("try")
		SA.checkBlock(st.tryblock, sym, i, jcode)
		jcode.append("catch(_ex){")
		jcode.append("var __ex=_ex;")
		if SGlobal.throwable_class==None:
			SGlobal.throwable_class=SHelper.getClassOnFullName("java.lang.Throwable")
			if SGlobal.throwable_class==None:
				raise Exception("Critical:class not found java.lang.Throwable")
		m=SGlobal.throwable_class.getMethodWithThisAccess("__valueOf",[SGlobal.objclass.mytype], True, None, None)
		code = []
		code.append("__ex=" + SGlobal.throwable_class.getPrototype()+".$."+ m.method.getJSName() + "(__ex);");
		add_else = False
		for ct in st.catches:
			sym.append({})
			sym[i + 1][ct.param.name.data] = ct.param
			if WAFConfig.isMinify():
				name = SA.getNextLocalSymbol(sym, "l")
				ct.param.js_name = name
				sym[0][0][name] = 1
			else:
				sym[0][0][ct.param.name.data] = 1
				ct.param.js_name = ct.param.name.data
			if add_else == True:
				code.append("else if(__ex instanceof " + ct.param.typ.coit.clazz.getPrototype() + ")");
			else:
				code.append("if(__ex instanceof " + ct.param.typ.coit.clazz.getPrototype() + ")");
			#SA.checkBlock(ct.block,sym,i+1,code)
			sym.append({})
			
			code.append("{")
			code.append(["var " + ct.param.getJSName() + "=__ex;"])
			cbcode = []
			SA.checkBlockStatements(ct.block.block, sym, i + 1, cbcode)
			code.append(cbcode)
			code.append("}")
			sym.pop()

			sym.pop()
			add_else = True
		code.append("else throw __ex;")
		jcode.append(code)
		jcode.append("}")
		if st.finallyblock != None:
			jcode.append("finally")
			SA.checkBlock(st.finallyblock, sym, i, jcode)
		
	@staticmethod
	def checkStmtExp(st, sym, i, jcode):#complete
		code = []
		r = SA.checkExpression(st.exp, sym, i, code)
		jcode.append(code[0] + ";")
		return r

	@staticmethod
	def checkParExpression(e, sym, i, jcode):#complete
		code = []
		r = SA.checkExpression(e.exp, sym, i, code)
		line = "(" + code[0] + ")"
		jcode.append(line)
		return r



	@staticmethod
	def checkLocalVariableDeclaration(lvd, sym, i, jcode):#complete
		line = "var "
		count = 0
		l = len(lvd.vds)
		for vd  in lvd.vds:
			code = []
			SA.checkVariableDeclarator(vd, lvd.modifiers, sym, i, code)
			line += code[0]
			count += 1
			if count == l: break
			line += ","
		jcode.append(line)
		#TODO:add symbols here

	@staticmethod
	def checkVariableDeclarator(vd, modifiers, sym, i, jcode):#complete
		t = vd.typ
		SHelper.processType(t, SA.currentClass, SA.currentMethod)
		
		if vd.name.data == None:raise WAFCompileError(-1, "Critical Error")
		if sym[i].has_key(vd.name.data):
			print "Duplicate variable in same block ", line
			print line
			print vd.name.lineno, vd.name.pos
			raise WAFCompileError(1001, vd.name)
		sym[i][vd.name.data] = vd#Var(line,vd.typ,vd.arraydim,modifiers)#TODO;what the hell is this
		if WAFConfig.isMinify():
			name = SA.getNextLocalSymbol(sym, "l")
			vd.js_name = name
			sym[0][0][name] = 1
		else:
			sym[0][0][vd.name.data] = 1
			vd.js_name = vd.name.data
		line = vd.getJSName()
		if vd.init != None:
			code = []
			t2 = SA.checkVariableInitializer(vd.init, sym, i, code)
			#################
			line = line + "=" + SA.getVariableInitializerCode(t, t2, code[0], vd.init)
		jcode.append(line)
	@staticmethod
	def getVariableInitializerCode(t1, t2, code, init):
		if SHelper.matchType(t1, t2):
			return code
		if not isinstance(init, ArrayInitializer):			
			_t2 = SA.getTypeIfConstant(init.parts)
			if _t2 != None:
				t2 = _t2
		if SA.isBasicType(t1) and SA.isBasicType(t2):
			d = SHelper.matchTypeAndGetDegree(t2, t1)
			if d == -1:
				raise WAFCompileError(1013, None)
			return code
		elif SA.isBasicType(t1) or SA.isBasicType(t2):
			if SA.isBasicType(t1):
				#unboxing
				if not SA.isWrapperClass(t2):raise "Can not assign value"
				u_t2 = SA.fromWrapperClassToBasic(t2)
				d = SHelper.matchTypeAndGetDegree(u_t2, t1)
				if d == -1:
					raise WAFCompileError(1013, None)
				return code + ".value"
			else:
				#TODO:make sure we have  wrapper her
				b_t2 = SA.fromBasicToWrapperClass(t2)
				d = SHelper.matchTypeAndGetDegree(b_t2, t1)
				if d == -1:
					raise WAFCompileError(1013, None)
				return SA.boxIt(t2, code)
		else:#both are object
			d = SHelper.matchTypeAndGetDegree(t2, t1)
			if d != -1:return code
			if SA.isWrapperClass(t1) and SA.isWrapperClass(t2):
				u_t1 = SA.fromWrapperClassToBasic(t1)
				u_t2 = SA.fromWrapperClassToBasic(t2)
				d = SHelper.matchTypeAndGetDegree(u_t2, u_t1)
				if d != -1:
					return SA.boxIt(u_t2, code + ".value")
			raise WAFCompileError(1013, None)



	@staticmethod
	def checkVariableInitializer(vi, sym, i, jcode):#complete
		if isinstance(vi, ArrayInitializer):
			return SA.checkArrayInitializer(vi, sym, i, jcode)
		else:#expression
			return SA.checkExpression(vi, sym, i, jcode)

	"""
		@staticmethod
		def checkArrayInitializer(ai, sym, i ,jcode):#complete #not_tested
				#TODO:J
				for vi in ai.part:
						SA.checkVariableInitializer(vi, sym, i ,jcode)
		"""
	@staticmethod
	def isDeclaration(t):
		return isinstance(t, STypeDeclaration)
	@staticmethod
	def getTypeDeclaration(t):
		if t == None:
			print "UnExpected: argument is null in getTypeDeclaration in java2js"
			some_method()
		if isinstance(t, Type) and t.coit != None:
			cls = t.coit.clazz
			if isinstance(cls, STypeDeclaration):
				return cls
			if isinstance(cls, TypeParameter):
				if cls.bound != None:
					if len(cls.bound) == 1:
						return cls.bound[0].coit.clazz
					else:
						print "Multiple bounds"
						some_method()
				return SGlobal.objclass
			print SA.ttos(cls)
			print "UnExpected: unexpected argument in getTypeDeclaration in java2js"
			some_method()
		elif isinstance(t, STypeDeclaration):
			return t
		else:
			print SA.ttos(t)
			print "UnExpected: unexpected argument in getTypeDeclaration in java2js"
			some_method()
	@staticmethod
	def mapTypeToTypeArgument(_typeargs, type):
		if _typeargs == None: return type
		if isinstance(type, Type) and type.coit != None and isinstance(type.coit.clazz, TypeParameter):
			for t in _typeargs:
				if t.ref == type.coit.clazz:
					if t.isany == False:
						return t.typ
					if t.extends != None:
						return t.extends
					if t.superclass != None:
						return t.superclass
					if t.isany == True:
						return SGlobal.objclass.mytype
					print "UnExpected"
					some_method()
						
		return type
	@staticmethod
	def applyJSTypeCastForArguments(method, argstl, code):
		for i in range(len(method.pars)):
			p = method.pars[i]
			a = argstl[i]
			code[i] = SA.applyJSTypeCast(a, p.typ, code[i])
	@staticmethod
	def applyJSTypeCastForArguments2(types, argstl, code):
		for i in range(len(types)):
			p = types[i]
			a = argstl[i]
			code[i] = SA.applyJSTypeCast(a, p, code[i])
	@staticmethod
	def applyJSTypeCast(curType, targetType, code):
		tc = SHelper.getClassOnFullName("com.openwaf.core.framework.TypeCast")
		if SA.isBasicType(curType) and SA.isBasicType(targetType):
			if SA.isBasicNumericType(curType) and SA.isBasicNumericType(targetType):
				v = targetType.pm_type.value
				if curType.pm_type.value <= v: return code #not necessory
				if v == PrimitiveType.BYTE:
					return tc.getPrototype() + ".$.rb(" + code + ")"
				if v == PrimitiveType.CHAR:
					return tc.getPrototype() + ".$.rc(" + code + ")"
				if v == PrimitiveType.INT:
					return tc.getPrototype() + ".$.ri(" + code + ")"
				if v == PrimitiveType.SHORT:
					return tc.getPrototype() + ".$.rs(" + code + ")"	
				return code#ingnoring right now could be long float double
			return code
		if SA.isBasicType(curType) or SA.isBasicType(targetType):
			if SA.isBasicType(curType):
				if SA.isWrapperClass(targetType):
					b_tar = SA.fromWrapperClassToBasic(targetType)
					code = SA.applyJSTypeCast(curType, b_tar, code)
					return SA.boxIt(b_tar, code)
				elif targetType.coit != None and targetType.coit.clazz == SGlobal.objclass:
					return SA.boxIt(curType, code)
				return code#nothing much we can do here
			else:
				if SA.isWrapperClass(curType):
					#we need to unbox
					if not SA.canUnbox(curType):return code
					ub_cur = SA.fromWrapperClassToBasic(curType)
					return SA.applyJSTypeCast(ub_cur, targetType, code + ".value")
				return code#nothing much we can do there
		return code
		

	@staticmethod
	def checkDotDotExpression(curType, parts, pi, pcount, sym, i, jcode):
		#TODO:temp solution
		if len(jcode) == 0:jcode.append("")
		if SA.isDeclaration(curType):#for static
			method_type_args = None
			if isinstance(parts[pi], ExTypeArguments):
				method_type_args = []				
				for arg in parts[pi].typeargs:
					SHelper.processType(arg, SA.currentClass, SA.currentMethod)
					ta = TypeArgument()
					ta.isany = False              		
					ta.typ = curType.mytype.mapAndConvertType(arg, None, SA.currentMethod)
					method_type_args.append(ta)
				pi += 1
			if isinstance(parts[pi], ExIdentifier):
				name = parts[pi].name.data
				if (pi + 1) < pcount and isinstance(parts[pi + 1], ExArguments):
					args = parts[pi + 1].arguments
					code = []
					argstl = SA.getExpressionListToTypeList(args, sym, i, code)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curType.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
					argstl = _argstl
					m = None					
					m = curType.getMethodWithThisAccess(name, argstl, True, method_type_args, SA.currentClass)
					if m == None:
						cc = SA.getTypeDeclaration(curType)
						print name
						m = curType.getMethodWithThisAccess(name, argstl, True, method_type_args, SA.currentClass)
						print cc.fullname
						print parts[pi].name.lineno
						raise WAFCompileError(1008, parts[pi].name)
					#if not m.isStatic():
					#		raise WAFCompileError(1014, parts[pi].name)
					SA.applyJSTypeCastForArguments(m, argstl, code)
					jcode[0] += m.method.getJSName() + "(" + ",".join(code) + ")"
					if m.method.is_void == True:return None
					r = curType.mytype.mapAndConvertType(m.rtype, method_type_args, m.method)
					if pi + 2 == pcount:return r
					#TODO:here could be array
					if isinstance(parts[pi + 2], ExDot):
						jcode[0] += "."
						return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i, jcode)
					if isinstance(parts[pi + 2], ExArrayIndex):
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
					raise WAFCompileError(0, "what is this in method")

				else:
					f = None
					f = curType.getFieldWithThisAccess(name, True, SA.currentClass)
					if f == None:
						print name
						print curType.fullname
						print name, SA.currentClass.fullname, SA.currentMethod.name, curType.fullname
						raise WAFCompileError(1008, parts[pi].name)
					jcode[0] += f.field.getJSName()
					if pi + 1 == pcount:return f.type
					if isinstance(parts[pi + 1], ExDot):
						jcode[0] += "."
						return SA.checkDotDotExpression(f.type, parts, pi + 2, pcount, sym, i, jcode)
					if isinstance(parts[pi + 1], ExArrayIndex):
						return SA.checkDotDotExpression(f.type, parts, pi + 1, pcount, sym, i, jcode)
						"""
						######
						code = []
						t = SA.checkExpression(parts[pi + 1].exp, sym, i, code)
						if not SA.canBeArrayIndex(t):
							raise WAFCompileError("Can not evalute to positive integer")
						######
						jcode[0] += "[" + code[0] + "]"
						if pi + 2 == pcount:
							return SA.getTypeWithReducedArray(f.type)
						else:
							if isinstance(parts[pi + 2], ExDot):
								jcode[0] += "."
								return SA.checkDotDotExpression(SA.getTypeWithReducedArray(f.type), parts, pi + 3, pcount, sym, i, jcode)
						"""
					raise WAFCompileError(0, "what is this")
			elif  isinstance(parts[pi], ExClass):
				jcode[0] += "_clz"
				if pi + 1 == pcount:
					return SHelper.getClassOnFullName("java.lang.Class").mytype
				if isinstance(parts[pi + 1], ExDot):
					jcode[0] += "."
					return SA.checkDotDotExpression(curType, parts, pi + 2, pcount, sym, i, jcode)
					#TODO:Process
			elif isinstance(parts[pi], ExThis):
				jcode[0] += "this._pi"
				if pi + 1 == pcount:
					return curType.mytype
				if isinstance(parts[pi + 1], ExDot):
					jcode[0] += "."
					return SA.checkDotDotExpression(curType.mytype, parts, pi + 2, pcount, sym, i, jcode)

			print "Not Handled 977/1851"
			print SA.toSParts(parts)
			some_method()




		SHelper.processType(curType, SA.currentClass, SA.currentMethod)
		method_type_args = None
		if isinstance(parts[pi], ExTypeArguments):
			method_type_args = []				
			for arg in parts[pi].typeargs:
				SHelper.processType(arg, SA.currentClass, SA.currentMethod)
				ta = TypeArgument()
				ta.isany = False              		
				ta.typ = curType.mapAndConvertType(arg, None, SA.currentMethod)
				method_type_args.append(ta)
			pi += 1
		if curType.coit != None:
			if isinstance(parts[pi], ExIdentifier):
				name = parts[pi].name.data
				if (pi + 1) < pcount and isinstance(parts[pi + 1], ExArguments):
					######### FOR IE 6
					#if accessing dom and compatibility is requested for IE 6/7
					if curType.coit.clazz.package == "com.openwaf.client.dom" and WAFConfig.isCompatibleWithIE67():
						args = parts[pi + 1].arguments
						code = []
						argstl = SA.getExpressionListToTypeList(args, sym, i, code)
						#mapping not required
						cc = curType.coit.clazz
						m = curType.getMethodWithThisAccess(name, argstl, False, method_type_args, SA.currentClass)
						if m == None:
							raise WAFCompileError(1008, name)
						SA.applyJSTypeCastForArguments(m, argstl, code)
						if m.method.method.block == None and m.method.method.native_code == None:
							#can not minify this
							jcode[0] += m.method.getJSName() + "(" + ",".join(code) + ")"								
							rtype = m.rtype
							if pi + 2 == pcount:return rtype
							if isinstance(parts[pi + 2], ExDot):
								jcode[0] += "."
								return SA.checkDotDotExpression(rtype, parts, pi + 3, pcount, sym, i, jcode)
							if isinstance(parts[pi + 2], ExArrayIndex):
								return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
							raise WAFCompileError(0, "what is this in method")
						else:
							if len(jcode[0]) > 0 and jcode[0][-1] == ".":jcode[0] = jcode[0][:-1]							
							line = cc.getPrototype() + ".$." + m.method.getJSName() + ".call("
							if len(code) > 0:
								jcode[0] = line + jcode[0] + "," + ",".join(code) + ")"
							else:
								jcode[0] = line + jcode[0] + ")"
							rtype = m.rtype
							if pi + 2 == pcount:return rtype
							if isinstance(parts[pi + 2], ExDot):
								jcode[0] += "."
								return SA.checkDotDotExpression(rtype, parts, pi + 3, pcount, sym, i, jcode)
							if isinstance(parts[pi + 2], ExArrayIndex):								
								return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
							raise WAFCompileError(0, "what is this in method")
						
					######### FOR IE 6
					args = parts[pi + 1].arguments
					code = []
					argstl = SA.getExpressionListToTypeList(args, sym, i, code)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curType.mapAndConvertType(_arg, None, SA.currentMethod))
					argstl = _argstl
					if name == "setCellData":
						print "setCellData"
					m = curType.getMethodWithThisAccess(name, argstl, False, method_type_args, SA.currentClass)
					if m == None:
						print SA.ttos(curType)
						print SA.currentClass.fullname
						cc = SA.getTypeDeclaration(curType)
						print cc.fullname
						print parts[pi].name.lineno
						print name
						raise WAFCompileError(1008, parts[pi].name)
					SA.applyJSTypeCastForArguments2(curType.mappAllPars(m, method_type_args, SA.currentMethod), argstl, code)
					if m.method.isAbstract():
						if WAFConfig.isMinify() == False:
							jcode[0] += m.method.getName() + "_" + str(m.method.mid) + "(" + ",".join(code) + ")"						
						else:
							jcode[0] += "_" + str(m.method.mid) + "(" + ",".join(code) + ")"
					else:
						jcode[0] += m.method.getJSName() + "(" + ",".join(code) + ")"
					if m.method.is_void == True:return None
					rtype = curType.mapAndConvertType(m.rtype, method_type_args, m)	
					if pi + 2 == pcount:return rtype
					if isinstance(parts[pi + 2], ExDot):
						jcode[0] += "."
						return SA.checkDotDotExpression(rtype, parts, pi + 3, pcount, sym, i, jcode)
					if isinstance(parts[pi + 2], ExArrayIndex):						
						return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
					raise WAFCompileError(0, "what is this in method")
				else:
					f = curType.getFieldWithThisAccess(name, False, SA.currentClass)
					if f == None:raise WAFCompileError(1009, parts[pi].name)
					jcode[0] += f.field.getJSName()
					ftype = curType.mapAndConvertType(f.type, None, SA.currentMethod)
					if pi + 1 == pcount:return ftype
					if isinstance(parts[pi + 1], ExDot):
						jcode[0] += "."
						return SA.checkDotDotExpression(ftype, parts, pi + 2, pcount, sym, i, jcode)
					if isinstance(parts[pi + 1], ExDot):					
						return SA.checkDotDotExpression(ftype, parts, pi + 1, pcount, sym, i, jcode)
					raise WAFCompileError(0, "what is this")
			elif isinstance(parts[pi], ExArrayIndex):
				if  curType.coit == None or curType.coit.clazz != SGlobal.arrayclass:
					raise WAFCompileError(-1, "Not an array exception")
				p = parts[pi]
				code = []
				t = SA.checkExpression(p.exp, sym, i, code)
				if not SA.canBeArrayIndex(t):
					raise WAFCompileError("Can not evalute to positive integer")
				jcode[0] += "[" + code[0] + "]"
				if pi + 1 == pcount:
					return SA.getTypeWithReducedArray(curType)
				else:
					if isinstance(parts[pi + 1], ExDot):
						jcode[0] += "."
						return SA.checkDotDotExpression(SA.getTypeWithReducedArray(curType), parts, pi + 2, pcount, sym, i, jcode)
					if isinstance(parts[pi + 1], ExArrayIndex):
						return SA.checkDotDotExpression(SA.getTypeWithReducedArray(curType), parts, pi + 1, pcount, sym, i, jcode)

				print "UnExpected:unexpected sequence"
				some_method()
			else:
				raise WAFCompileError("What is this")
		else:
			if isinstance(parts[pi], ExArrayIndex):
				if curType.coit == None or curType.coit.clazz != SGlobal.arrayclass:
					raise WAFCompileError(-1, "Not an array exception")
				p = parts[pi]
				code = []
				t = SA.checkExpression(p.exp, sym, i, code)
				if not SA.canBeArrayIndex(t):
					raise WAFCompileError("Can not evalute to positive integer")
				jcode[0] += "[" + code[0] + "]"
				r = SA.getTypeWithReducedArray(curType)
				if pi + 1 == pcount:return r					
				if isinstance(parts[pi + 1], ExDot):
					jcode[0] += "."
					return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
				if isinstance(parts[pi + 1], ExArrayIndex):	
					return SA.checkDotDotExpression(r, parts, pi + 1, pcount, sym, i, jcode)
				print "UnExpected:unexpected sequence"
				some_method()	
			else:
				raise WAFCompileError(-1, "What is this")


	@staticmethod
	def getExpressionListToTypeList(el, sym, i, jcode):#incomplete tested
		ts = []
		for e in el:
			code = []
			r = SA.checkExpression(e, sym, i, code)
			if r == None:
				for p in el:
					print SA.toSParts(p.parts)
				print code
				raise WAFCompileError(0, "Invalid argument")#TODO:change this
			ts.append(r)
			jcode.append(code[0])
		return ts
	@staticmethod
	def checkExpression(e, sym, i, jcode):#incomplete
		if len(jcode) == 0:jcode.append("")
		return SA.checkExpressionArray(e.parts, sym, i, jcode)

	@staticmethod
	def isExpressionTuple(p):#incomplete
		if not isinstance(p, list):return False
		l = len(p)
		if l > 3 or l < 1:return False
		if l == 2 and isinstance(p[0], ExOperator):
			return True
		elif (l == 2 or l == 3) and isinstance(p[1], ExOperator):
			return True
		return False
	@staticmethod
	def checkTuplePart(part, sym, i, jcode):
		if len(jcode) == 0:jcode.append("")
		if SA.isExpressionTuple(part):
			return SA.checkExpressionTuple(part, sym, i, jcode)
		elif isinstance(part, ExPrimary):
			return SA.checkExpressionArray(part.parts, sym, i, jcode)
		else:
			return SA.checkExpressionArray(part, sym, i, jcode)
	@staticmethod
	def checkExpressionTuple(p, sym, i, jcode):

		l = len(p)
		if l == 2 and isinstance(p[0], ExOperator):
			o = p[0]
			jcode[0] += SA.checkOperator(p[0].value, sym, i)
			if not o.value >= OprUnary.INC and o.value <= OprUnary.TILDE:
				raise WAFCompileError(-1, "Wrong operator prefix")#TODO
			t = SA.checkTuplePart(p[1], sym, i, jcode)
			if o.value == OprUnary.TILDE:
				if not (SA.isBasicNumericType(t) and t.pm_type.value in [ PrimitiveType.INT, PrimitiveType.LONG, PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]):
					raise WAFCompileError(1011, None)
				if t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return t#int or long
			elif o.value == OprUnary.NOT:
				if not(SA.isBasicType(t)  and t.pm_type.value == PrimitiveType.BOOLEAN):
					raise WAFCompileError(1012, None)
				return t
			elif o.value in [OprUnary.DEC, OprUnary.INC]:
				if not SA.isBasicNumericType(t):
					raise WAFCompileError(1013, None)
				return t
			elif o.value in [OprUnary.NEGATIVE, OprUnary.POSITIVE]:
				if not SA.isBasicNumericType(t):
					raise WAFCompileError(1013, None)
				if t.pm_type.value in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return t
			raise WAFCompileError(-1, "Critical Error 464")
		elif l == 2 and isinstance(p[1], ExOperator):
			o = p[1].value
			t = None
			t = SA.checkTuplePart(p[0], sym, i, jcode)
			if not o in [OprPostfix.DEC, OprPostfix.INC]:
				raise WAFCompileError(-1, "Wrong Operaor postfix")#TODO
			if not SA.isBasicNumericType(t):
				raise WAFCompileError(1013, None)
			jcode[0] += SA.checkOperator(p[1].value, sym, i)
			return t
		elif l == 3 and isinstance(p[1], ExOperator):
			o = p[1].value
			lcode = []
			rcode = []
			t1 = SA.checkTuplePart(p[0], sym, i, lcode)
			t2 = SA.checkTuplePart(p[2], sym, i, rcode)
			if o in [OprMultiplicative.DIVIDE, OprMultiplicative.MULTIPY, OprMultiplicative.MOD, OprAdditive.MINUS, OprAdditive.PLUS, OprBinary.AND, OprBinary.OR, OprBinary.XOR]:
				if o == OprAdditive.PLUS:
					if SA.isStringType(t1) or SA.isStringType(t2):
						jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
						return SGlobal.stringclass.mytype
				if SA.isBasicNumericType(t1) and SA.isBasicNumericType(t2):
					dt1 = t1.pm_type.value
					dt2 = t2.pm_type.value
					if o in [OprBinary.AND, OprBinary.OR, OprBinary.XOR]:
						if dt1 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
							raise "Shift can not be applied on float or double"
						if dt2 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
							raise "Shift can not be applied on float or double"
					dt = max(dt1, dt2)
					jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
					if dt in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
						return SGlobal.basictypes[PrimitiveType.INT]
					return SGlobal.basictypes[dt]
				elif (SA.isBasicNumericType(t1) and SA.isWrapperClass(t2)) or (SA.isBasicNumericType(t2) and SA.isWrapperClass(t1)):
					if SA.isBasicNumericType(t1):
						if not SA.canUnbox(t2):raise "Can not unbox "
						ub_dt2 = SA.fromWrapperClassToBasic(t2)
						dt1 = t1
						if o in [OprBinary.AND, OprBinary.OR, OprBinary.XOR]:
							if dt1.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
								raise "Shift can not be applied on float or double"
							if ub_dt2.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
								raise "Shift can not be applied on float or double"
						jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0] + ".value"
						dt = max(dt1.pm_type.value, ub_dt2.pm_type.value)
						if dt in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
							return SGlobal.basictypes[PrimitiveType.INT]
						return SGlobal.basictypes[dt]
					else:
						if not SA.canUnbox(t1):raise "Can not unbox "
						ub_dt1 = SA.fromWrapperClassToBasic(t1)
						dt2 = t2
						if o in [OprBinary.AND, OprBinary.OR, OprBinary.XOR]:
							if dt2.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
								raise "Shift can not be applied on float or double"
							if ub_dt1.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
								raise "Shift can not be applied on float or double"
						dt = max(dt2.pm_type.value, ub_dt1.pm_type.value)
						jcode[0] += lcode[0] + ".value" + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
						if dt in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
							return SGlobal.basictypes[PrimitiveType.INT]
						return SGlobal.basictypes[dt] 					
				elif SA.isWrapperClass(t1) or SA.isWrapperClass(t2):
					if not SA.canUnbox(t1):raise "Can not unbox"
					if not SA.canUnbox(t2):raise "Can not unbox"
					ub_dt1 = SA.fromWrapperClassToBasic(t1)
					ub_dt2 = SA.fromWrapperClassToBasic(t2)
					if o in [OprBinary.AND, OprBinary.OR, OprBinary.XOR]:
						if ub_dt1.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
							raise "Shift can not be applied on float or double"
						if ub_dt2.pm_type.value in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
							raise "Shift can not be applied on float or double"
					dt = max(ub_dt1.pm_type.value, ub_dt2.pm_type.value)
					jcode[0] += lcode[0] + ".value" + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0] + ".value"
					if dt in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
						return SGlobal.basictypes[PrimitiveType.INT]
					return SGlobal.basictypes[dt]
				raise WAFCompileError(1013, None)

			elif o in [OprShift.LEFT_SHIFT, OprShift.RIGHT_SHIFT, OprShift.RIGHT_RIGHT_SHIFT]:
				jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
				if (not SA.isBasicNumericType(t1)) or (not SA.isBasicNumericType(t2)):
					raise WAFCompileError(1013, None)
				dt1 = t1.pm_type.value
				dt2 = t2.pm_type.value
				if dt1 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
					raise "Shift can not be applied on float or double"
				if dt2 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
					raise "Shift can not be applied on float or double"
				dt = dt1#NOTE:int shift left operand is important
				if dt in [PrimitiveType.BYTE, PrimitiveType.CHAR, PrimitiveType.SHORT]:
					return SGlobal.basictypes[PrimitiveType.INT]
				return SGlobal.basictypes[dt]
			elif o == OprInstanceOf.INSTANCEOF:
				#TODO:reducet this
				#TODO:optimize this
				tc = SHelper.getClassOnFullName("com.openwaf.core.framework.TypeCast")
				m = tc.getMethodWithThisAccess("instanceOf", [SGlobal.objclass.mytype, SGlobal.objclass.mytype], True, None, None)
				jcode[0] += tc.getPrototype() + ".$." + m.method.getJSName() + "(" + lcode[0] + "," + rcode[0] + ")"
				return SGlobal.basictypes[PrimitiveType.BOOLEAN]
				
			elif o in [ OprEquality.ET, OprEquality.NET, OprLogical.AND, OprLogical.OR, OprRelational.GT, OprRelational.GTE, OprRelational.LT, OprRelational.LTE]:
				if SA.isBasicType(t1) and SA.isBasicType(t2):
					jcode[0] += lcode[0] + SA.checkOperator(p[1].value, sym, i) + rcode[0]
				elif SA.isBasicType(t1) or SA.isBasicType(t2):
					if SA.isBasicType(t1):
						if SA.isWrapperClass(t2):
							jcode[0] += lcode[0] + SA.checkOperator(p[1].value, sym, i) + rcode[0] + ".value"
						else:
							raise "Can not compare these data types"
					else:
						if SA.isWrapperClass(t1):
							jcode[0] += lcode[0] + ".value" + SA.checkOperator(p[1].value, sym, i) + rcode[0]
						else:
							raise "Can not compare these data types"
				else:#both are object
					if SA.isWrapperClass(t1) and SA.isWrapperClass(t2):
						jcode[0] += lcode[0] + ".value" + SA.checkOperator(p[1].value, sym, i) + rcode[0] + ".value"
					else:
						#nothing much we can do here
						jcode[0] += lcode[0] + SA.checkOperator(p[1].value, sym, i) + rcode[0]
					
				
				return SGlobal.basictypes[PrimitiveType.BOOLEAN]
			elif o in [ OprAssign.NORMAL, OprAssign.PLUS, OprAssign.MINUS, OprAssign.MULTIPLY, OprAssign.DIVIDE, OprAssign.MOD, OprAssign.AND, OprAssign.XOR, OprAssign.OR, OprAssign.LEFT_SHIFT, OprAssign.RIGHT_SHIFT, OprAssign.RIGHT_RIGHT_SHIFT]:
				if o == OprAssign.NORMAL or o == OprAssign.PLUS:
					if SHelper.matchType(t1, t2):
						jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
						return t1
					if o == OprAssign.NORMAL:
						_t2 = SA.getTypeIfConstant(p[2])
						if _t2 != None:
							t2 = _t2
					if SA.isBasicType(t1) and SA.isBasicType(t2):
						d = SHelper.matchTypeAndGetDegree(t2, t1)
						if d == -1:
							raise WAFCompileError(1013, None)
						jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
						return t1
					elif SA.isBasicType(t1) or SA.isBasicType(t2):
						if SA.isBasicType(t1):
							#unboxing
							u_t2 = SA.fromWrapperClassToBasic(t2)
							d = SHelper.matchTypeAndGetDegree(u_t2, t1)
							if d == -1:
								raise WAFCompileError(1013, None)
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0] + ".value"
							return t1
						else:
							#TODO:make sure we have  wrapper her
							b_t2 = SA.fromBasicToWrapperClass(t2)
							d = SHelper.matchTypeAndGetDegree(b_t2, t1)
							if d == -1:
								raise WAFCompileError(1013, None)
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
							return SA.fromWrapperClassToBasic(t1)
					else:#both are object
						
						d = SHelper.matchTypeAndGetDegree(t2, t1)
						if d != -1:
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
							return t1	
						if SA.isWrapperClass(t1) and SA.isWrapperClass(t2):
							u_t1 = SA.fromWrapperClassToBasic(t1)
							u_t2 = SA.fromWrapperClassToBasic(t2)
							d = SHelper.matchTypeAndGetDegree(u_t2, u_t1)
							if d != -1:
								jcode[0] += lcode[0] + ".value" + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0] + ".value"
								return t1
						raise WAFCompileError(1013, None)
				if (not SA.isBasicNumericType(t1)) or (not SA.isBasicNumericType(t2)):
					raise WAFCompileError(1013, None)
				dt1 = t1.pm_type.value
				dt2 = t2.pm_type.value 
				if o in [OprAssign.MINUS, OprAssign.MULTIPLY, OprAssign.DIVIDE, OprAssign.MOD]:
					jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
					return SGlobal.basictypes[dt1]
				elif o in [OprAssign.AND , OprAssign.OR, OprAssign.XOR, OprAssign.LEFT_SHIFT, OprAssign.RIGHT_SHIFT, OprAssign.RIGHT_RIGHT_SHIFT]:
					jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
					if dt1 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
						raise "Shift can not be applied on float or double"
					if dt2 in [PrimitiveType.FLOAT, PrimitiveType.DOUBLE]:
						raise "Shift can not be applied on float or double"
					return SGlobal.basictypes[dt1]
				else:some_method()
			elif o in [OprTernary.IF, OprTernary.ELSE]:
				if o == OprTernary.IF:
					if not SA.isBasicType(t1):raise "Expecting boolean in ternary operator"
					dt1 = t1.pm_type.value
					if dt1 != PrimitiveType.BOOLEAN:raise "Expecting boolean in ternary operator"
					jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
					return t2;
				else:
					if SA.isBasicType(t1) and SA.isBasicType(t2):						
						dt1 = t1.pm_type.value
						dt2 = t2.pm_type.value
						if SA.isBasicNumericType(t1) and SA.isBasicNumericType(t2):
							dt = max(dt1, dt2)
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
							return SGlobal.basictypes[dt]
						elif dt1 == PrimitiveType.BOOLEAN and dt2 == PrimitiveType.BOOLEAN:
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
							return t1
						else:
							raise "Uncompatible datatype in ternary else"
					elif SA.isBasicType(t1) or SA.isBasicType(t2):
						#one of them is basic , and one is object
						if SA.isBasicType(t1):
							if SA.canUnbox(t2):
								ub_t2 = SA.fromWrapperClassToBasic(t2)#unboxed
								dt1 = t1.pm_type.value
								dt2 = ub_t2.pm_type.value
								jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0] + ".value"
								return SGlobal.basictypes[max(dt1, dt2)]
							else:
								#This mean we have to box the basic type
								b_t1 = SA.fromBasicToWrapperClass(t1)
								clz2 = SA.getClassForType(t2)
								d1 = b_t1.coit.clazz.getDegreeWithThis(clz2)
								d2 = clz2.getDegreeWithThis(b_t1.coit.clazz)
								if d1 != -1 and d2 != -1:
									#TODO:this is modtly possible ternary else returngin same object
									if d1 > d2:
										jcode[0] += SA.boxIt(t1, lcode[0]) + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
										return b_t1
									else:
										jcode[0] += SA.boxIt(t1, lcode[0]) + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
										return t2
								elif d1 != -1 or d2 != -1:
									if d1 != -1:
										jcode[0] += SA.boxIt(t1, lcode[0]) + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
										return t2
									else:
										jcode[0] += SA.boxIt(t1, lcode[0]) + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
										return b_t1
								else:
									#wrap t1
									jcode[0] += SA.boxIt(t1, lcode[0]) + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
									return SGlobal.objclass.mytype 
						else:
							#t1 is object
							if SA.canUnbox(t1):
								ub_t1 = SA.fromWrapperClassToBasic(t1)#unboxed
								dt1 = t2.pm_type.value
								dt1 = ub_t1.pm_type.value
								jcode[0] += lcode[0] + ".value" + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
								return SGlobal.basictypes[max(dt1, dt2)]
							else:
								#This mean we have to box the basic type
								b_t2 = SA.fromBasicToWrapperClass(t2)
								clz1 = SA.getClassForType(t1)
								d1 = b_t2.coit.clazz.getDegreeWithThis(clz1)
								d2 = clz1.getDegreeWithThis(b_t2.coit.clazz)
								if d1 != -1 and d2 != -1:
									#TODO:this is modtly possible ternary else returngin same object
									if d1 > d2:
										jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
										return b_t2
									else:
										jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
										return t1
								elif d1 != -1 or d2 != -1:
									if d1 != -1:
										jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
										return t1
									else:
										jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
										return b_t2
								else:
									#wrap t1
									jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + SA.boxIt(t2, rcode[0])
									return SGlobal.objclass.mytype 
					else:
						clz1 = SA.getClassForType(t1)
						clz2 = SA.getClassForType(t2)
						d1 = clz1.getDegreeWithThis(clz2)
						d2 = clz2.getDegreeWithThis(clz1)
						if d1 != -1 and d2 != -1:
							#TODO:this is modtly possible ternary else returngin same object
							if d1 > d2:
								jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
								return t2
							else:
								jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
								return t1
						elif d1 != -1 or d2 != -1:
							if d1 != -1:
								jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
								return t1
							else:
								jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
								return t2
						else:
							#wrap t1
							jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
							return SGlobal.objclass.mytype
				some_method()
			else:
				jcode[0] += lcode[0] + " " + SA.checkOperator(p[1].value, sym, i) + " " + rcode[0]
				return t1
			#TODO:need to do lots of checking skipping for time being
			#if o>=OprAssign.NORMAL and o<=OprAssign.RIGHT_RIGHT_SHIFT:
		else:
			raise WAFCompileError(-1, "Unkwon combination for tuple 493")
	@staticmethod
	def getTypeIfConstant(p):
		if not(isinstance(p, list) and len(p) == 1) :return None
		p = p[0]
		if isinstance(p, ExLiteral):
			return SGlobal.getBasicTypeForLiteral2(p.literal)
		elif isinstance(p, ExPrimary):
			return SA.getTypeIfConstant(p.parts)		
		return None
		
	@staticmethod
	def checkExpressionTupleArray(parts, sym, si , jcode):
		#sanity check
		if len(parts) == 1:
			return SA.checkExpressionArray(parts[0], sym, si, jcode)
		if not(isinstance(parts[0], ExOperator) or isinstance(parts[1], ExOperator)):
			some_method()
		count = len(parts)
		#o1=ExOperator()
		#o2=ExOperator()
		i = 0
		stack = []
		out = []
		p = parts		
		while i < count:
			if isinstance(p[i], ExOperator):
				o1 = p[i]
				while len(stack) > 0 and isinstance(stack[len(stack) - 1], ExOperator):
					o2 = stack[len(stack) - 1]
					if o1.isLeftToRight() and o1.getPrecedance() >= o2.getPrecedance():
						out.append(stack.pop())
					elif o1.isRightToLeft() and o1.getPrecedance() > o2.getPrecedance():
						out.append(stack.pop())
					else:
						break
				stack.append(o1)
				i += 1			
			else:
				out.append(p[i])
				i += 1
		while len(stack) > 0:
			out.append(stack.pop())
		
		
		count = len(out)
		out2 = []
		for i in range(count):
			out2.append(out[count - i - 1])
		tc = [0] 
		r = SA.getResolvedExpression(out2, tc)
		if tc[0] != count:
			print tc[0]
			print count
			some_method()
		return SA.checkExpressionTuple(r, sym, si, jcode)
			
	@staticmethod
	def getResolvedExpression(a, consumed):
		count = len(a)
		if count == 0:
			raise "Error" 
		o = a[0]
		tor = []
		if not isinstance(o, ExOperator):
			tor.append(o)
			consumed[0] = 1
			return tor
		if o.value in [OprPostfix.DEC, OprPostfix.INC]:
			tc = [0]
			r = SA.getResolvedExpression(a[1:], tc)
			consumed[0] = 1 + tc[0]
			tor.append(r)
			tor.append(o)
			return tor
		elif o.value in [OprUnary.INC, OprUnary.DEC, OprUnary.NEGATIVE, OprUnary.NOT, OprUnary.POSITIVE, OprUnary.TILDE]:
			tc = [0]
			r = SA.getResolvedExpression(a[1:], tc)
			consumed[0] = 1 + tc[0]
			tor.append(o)
			tor.append(r)
			return tor
		else:
			tc = [0]
			r1 = SA.getResolvedExpression(a[1:], tc)
			consumed[0] = 1 + tc[0]
			tc = [0]
			r = SA.getResolvedExpression(a[consumed[0]:], tc)
			consumed[0] += tc[0]
			tor.append(r)
			tor.append(o)
			tor.append(r1)
			
			return tor
			
			
			
	@staticmethod
	def getTypeWithReducedArray(t):
		return t.coit.next
	@staticmethod
	def ttos(p):
		if type(p).__name__ == 'instance':
			return p.__class__.__name__
		else:
			return  type(p).__name__
	@staticmethod
	def toSParts(parts):
		s = ""
		for p in parts:
			if type(p).__name__ == 'instance':
				s += " " + p.__class__.__name__
				if isinstance(p, ExIdentifier):
					s += "(" + p.name.data + ")"
			else:
				s += "{ " + SA.toSParts(p) + " }"
		return s
	@staticmethod
	def getFieldFromCurrentClass(name, static_only=False):#ABSOLUTE
		cls = SA.currentClass
		f = cls.getFieldWithThisAccess(name, static_only, SA.currentClass)
		return f
	@staticmethod
	def getFieldFromContainerClass(name, static_only=False):
		cls = SA.currentClass
		f = cls.getFieldFromContainerClass(name, static_only, cls)
		return f
	@staticmethod
	def getMethodFromCurrentClass(name, args, static_only=False):#ABSOLUTE
		cls = SA.currentClass
		m = cls.getMethodWithThisAccess(name, args, static_only, None, SA.currentClass)
		#f=cls.getFieldWithThisAccess(name,only_static,SA.currentClass)
		return m
	@staticmethod
	def getMethodFromContainerClass(name, args, static_only=False):
		cls = SA.currentClass
		m = SClass.getMethodFromContainerClass(name, args, static_only, cls)
		#f=cls.getFieldWithThisAccess(name,only_static,SA.currentClass)
		return m




	@staticmethod
	def checkExpressionArray(parts, sym, i, jcode):
		if len(jcode) == 0:jcode.append("")
		if isinstance(parts, ExType):
			SHelper.processType(parts.typ, SA.currentClass, SA.currentMethod)
			if parts.typ.coit != None:
				jcode[0] += parts.typ.coit.clazz.getPrototype()			
			return parts.typ
		if not isinstance(parts, list):
			print "what is this" 
			some_method()
			return
		#print "Parts " + SA.toSParts(parts)
		if SA.isExpressionTuple(parts):
			return SA.checkExpressionTuple(parts, sym, i, jcode)
		pcount = len(parts)
		for pi in range(0, pcount):
			p = parts[pi]
			if isinstance(p, ExPrimary):
				#it can be followeb by selector and postfix operators ++,--
				r = SA.checkExpressionArray(p.parts, sym, i, jcode)
				if pi + 1 == pcount:return r
				np = parts[pi + 1]
				if isinstance(np, ExDot):
					jcode[0] += "."
					return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
				###########
				if isinstance(np, ExArrayIndex):
					return SA.checkDotDotExpression(r, parts, pi + 1 , pcount, sym, i, jcode)
					"""
					if r.coit == None or r.coit.clazz != SGlobal.arrayclass:
						raise WAFCompileError(-1, "Not an array")
					code = []
					t = SA.checkExpression(np.exp, sym, i, code)
					jcode[0] += "[" + code[0] + "]"
					if isinstance(t, Type):
						if not SA.canBeArrayIndex(t):
							raise WAFCompileError("Can not evalute to positive integer")
					if pi + 2 == pcount:return SA.getTypeWithReducedArray(r)
					code = []
					r = SA.checkDotDotExpression(SA.getTypeWithReducedArray(r), parts, pi + 2, pcount, sym, i, code)
					jcode[0] += code[0]
					return r
					"""
				###########
				raise WAFCompileError(-1, "Primary Error 535")
				#TODO:handle postfix operators ++,--

			elif isinstance(p, list):
				#if SA.isExpressionTuple(p):
				#		return SA.checkExpressionTuple(p, sym, i,jcode)
				#else:
				return SA.checkExpressionTupleArray(parts, sym, i, jcode)
			elif isinstance(p, ExThis):
				jcode[0] += "this"
				if pi + 1 == pcount:
					return SA.currentClass.mytype
				np = parts[pi + 1]
				#this()

				if isinstance(np, ExArguments):#calling another constructor
					code = []
					argstl = SA.getExpressionListToTypeList(np.arguments, sym, i, code)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
					argstl = _argstl
					cc = SA.currentClass.getConstructor(argstl, SA.currentClass)
					if  cc == None:
						raise WAFCompileError(1007, SA.currentClass.name)
					#TODO:J call another constructor here .. written below check this
					SA.applyJSTypeCastForArguments(cc, argstl, code)
					jcode[0] += "." + cc.getJSName() + "(" + ",".join(code) + ")"
					
					pi = pi + 1
				#this.member....
				elif isinstance(np, ExDot):
					pi = pi + 2
					p = parts[pi]
					jcode[0] += "."
					if pi + 1 == pcount:
						f = SA.currentClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						jcode[0] += f.field.getJSName()
						return SA.currentClass.mytype.mapAndConvertType(f.type, None, SA.currentMethod)
					np = parts[pi + 1]
					if isinstance(np, ExDot):
						f = SA.currentClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						jcode[0] += f.field.getJSName()
						jcode[0] += "."
						r = SA.currentClass.mytype.mapAndConvertType(f.type, None, SA.currentMethod)
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
					elif isinstance(np, ExArguments):
						#########
						args = np.arguments
						curType = SA.currentClass.mytype
						if curType.coit.clazz.package == "com.openwaf.client.dom" and WAFConfig.isCompatibleWithIE67():
							args = np.arguments
							code = []
							argstl = SA.getExpressionListToTypeList(args, sym, i, code)
							#mapping not required
							cc = curType.coit.clazz
							m = curType.getMethodWithThisAccess(p.name.data, argstl, False, None, SA.currentClass)
							if m == None:
								raise Exception("Method not found " + p.name)
							SA.applyJSTypeCastForArguments(m, argstl, code)
							if m.method.method.block == None and m.method.method.native_code == None:
								#can not minify this
								jcode[0] += m.method.getJSName() + "(" + ",".join(code) + ")"								
								r = m.rtype
								if m.method.is_void:return None
								if pi + 2 == pcount:return r
								if isinstance(parts[pi + 2], ExDot):
									jcode[0] += "."
									return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i, jcode)
								if isinstance(parts[pi + 2], ExDot):
									return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
								raise WAFCompileError(0, "what is this in method")
							else:
								if len(jcode[0]) > 0 and jcode[0][-1] == ".":jcode[0] = jcode[0][:-1]								
								line = cc.getPrototype() + ".$." + m.method.getJSName() + ".call("
								if len(code) > 0:
									jcode[0] = line + jcode[0] + "," + ",".join(code) + ")"
								else:
									jcode[0] = line + jcode[0] + ")"
								r = m.rtype
								if m.method.is_void:return None
								if pi + 2 == pcount:return r
								if isinstance(parts[pi + 2], ExDot):
									jcode[0] += "."
									return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i, jcode)
								if isinstance(parts[pi + 2], ExArrayIndex):									
									return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
								raise WAFCompileError(0, "what is this in method")
						
						#########
						args = np.arguments
						code = []
						argstl = SA.getExpressionListToTypeList(args, sym, i, code)
						_argstl = []
						for _arg in argstl: 
							_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
						argstl = _argstl
						#access_control=SA.getAccessControl(SA.currentClass,SA.currentClass)
						m = SA.currentClass.mytype.getMethodWithThisAccess(p.name.data, argstl, False, None, SA.currentClass)
						if m == None:
							raise "Method not found"
						SA.applyJSTypeCastForArguments(m, argstl, code)
						if m.method.isAbstract():
							if WAFConfig.isMinify() == False:
								jcode[0] += m.method.getName() + "_" + str(m.method.mid) + "(" + ",".join(code) + ")"
							else:
								jcode[0] +=  "_" + str(m.method.mid) + "(" + ",".join(code) + ")"
						else:
							jcode[0] += m.method.getJSName() + "(" + ",".join(code) + ")"
						#m = SA.currentClass.getMethodPrivateAccess(p.name.data, argstl, 0)
						if m == None:
							raise WAFCompileError(1009, p.name.data)
						if m.method.is_void:return None
						r = SA.currentClass.mytype.mapAndConvertType(m.rtype, None, SA.currentMethod)
						if pi + 2 == pcount:return r
						if isinstance(parts[pi + 2], ExDot):
							jcode[0] += "."
							return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i, jcode)
						if isinstance(parts[pi + 2], ExArrayIndex):
							return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
						raise WAFCompileError(0, "what is this in method")
					else:
						raise WAFCompileError(-1, "What the hell is this")
				else:
					raise WAFCompileError(-1, "What the hell is this")
			elif isinstance(p, ExIdentifier):
				name = p.name.data;
				if pi + 1 == pcount:
					t = SA.getVariable(name, sym, i)
					
					#if  SA.isDeclaration(t):
					#	jcode[0] += t.getPrototype()
					#	return t
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t != None:
							if t.field.isStatic():
								jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
							else:
								jcode[0] += "this." + t.field.getJSName()
						else:
							t = SA.getFieldFromContainerClass(name)
							if t == None:
								print p.name 
								raise WAFCompileError(1009, p.name)
							if t.field.isStatic():
								jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
							else:
								d = SA.currentClass.getDepthRelativeToThis(t.field.clazz)
								jcode[0] += "this" + ("._pi" * d) + "." + t.field.getJSName()
							#TODO:adjust code to acces if from parent class
					else:
						if isinstance(t, SEnum):
							jcode[0] += name
						else:
							jcode[0] += t.getJSName()
					t = SA.getTypeOfVariable(t)
					if t == None:
						raise WAFCompileError(1009, p.name)
					if  SA.isDeclaration(t):
						jcode[0] += t.getPrototype()
						return t
					return SA.currentClass.mapAndConvertType(SA.getTypeOfVariable(t), None, SA.currentClass, None, SA.currentMethod)#TODO:this is wrong i guess
				np = parts[pi + 1]
				if isinstance(np, ExDot) or isinstance(np, ExArrayIndex):
					t = SA.getVariable(name, sym, i)
					if t != None and isinstance(t, SPackage):
						npi = pi + 1
						pack_str = t.name 
						while  npi + 1 < pcount and isinstance(parts[npi], ExDot) and  isinstance(parts[npi + 1], ExIdentifier):
							p = parts[npi + 1]
							t = SA.getVariable(pack_str + "." + p.name.data, sym, i)
							npi += 2
							if isinstance(t, SPackage):
								pack_str += "." + p.name.data
							elif isinstance(t, STypeDeclaration):
								pack_str += "." + p.name.data
								break
							else:
								print t, pack_str + "." + p.name.data
								print "Error", some_method()
						if not isinstance(t, STypeDeclaration):
							print "Type not found", pack_str
							some_method()
						if npi + 1 == pcount:
							jcode[0] += t.getPrototype()
							return t
						np = parts[npi]
						if not isinstance(np, ExDot):
							print "Expecting dot(.)", some_method()
						npi = npi + 1
						if npi + 1 > pcount :
							print "Unexpected ", some_method()#TODO:ERROR REPORT
						np = parts[npi]
						if isinstance(np, ExThis):
							#depth goes her in java2js
							d = SA.currentClass.getDepthRelativeToThis(t)
							jcode[0] += "this" + ("._pi" * d)
							if npi + 1 == pcount:
								return t.mytype
							else:
								return SA.checkDotDotExpression(t.mytype, parts, npi + 1, pcount, sym, i, jcode)
						else:
							jcode[0] += t.getPrototype() + ".$."
							return SA.checkDotDotExpression(t, parts, npi, pcount, sym, i, jcode)
					if t != None and isinstance(t, STypeDeclaration):
						npi = pi + 1
						pack_str = t.name 
						cur_class = t
						while  npi + 1 < pcount and isinstance(parts[npi], ExDot) and  isinstance(parts[npi + 1], ExIdentifier):
							p = parts[npi + 1]
							t = cur_class.getInnerMember(p.name.data)
							if t == None:
								jcode[0] += cur_class.getPrototype() + ".$."
								return SA.checkDotDotExpression(cur_class, parts, npi + 1, pcount, sym, i, jcode)
							cur_class = t
							npi += 2
						t = cur_class
						if not isinstance(cur_class, STypeDeclaration):
							print "Type not found", pack_str
							some_method()
						if npi + 1 == pcount:
							jcode[0] += t.getPrototype()
							return t
						np = parts[npi]
						if not isinstance(np, ExDot):
							print "Expecting dot(.)", some_method()
						npi = npi + 1
						if npi + 1 > pcount :
							print "Unexpected ", some_method()#TODO:ERROR REPORT
						np = parts[npi]
						if isinstance(np, ExThis):
							#depth goes her in java2js
							d = SA.currentClass.getDepthRelativeToThis(t)
							jcode[0] += "this" + ("._pi" * d)
							if npi + 1 == pcount:
								return t.mytype
							else:
								return SA.checkDotDotExpression(t.mytype, parts, npi + 1, pcount, sym, i, jcode)
						else:
							jcode[0] += t.getPrototype() + ".$."
							return SA.checkDotDotExpression(t, parts, npi, pcount, sym, i, jcode)
							
							
								
							
							
							
					#if SA.isDeclaration(t):
					#	jcode[0] += t.getPrototype() + ".prototype."
					#	return SA.checkDotDotExpression(t, parts, pi + 2, pcount, sym, i, jcode)
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t != None:
							if t.field.isStatic():
								jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
							else:
								jcode[0] += "this." + t.field.getJSName()
						else:
							t = SA.getFieldFromContainerClass(name)#TODO:update from
							if t == None:
								raise WAFCompileError(1009, p.name)
							if t.field.isStatic():
								jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
							else:
								d = SA.currentClass.getDepthRelativeToThis(t.field.clazz)
								jcode[0] += "this" + ("._pi" * d) + "." + t.field.getJSName()
						
					else:
						jcode[0] += t.getJSName()
					t = SA.getTypeOfVariable(t)
					if t == None:
						print name
						raise WAFCompileError(1009, p.name)
					vtype = vtype = SA.currentClass.mapAndConvertType(SA.getTypeOfVariable(t), None, SA.currentClass, None, SA.currentMethod)
					if isinstance(np, ExDot):
						
						jcode[0] += "."
						if vtype.coit != None:#coit type
							return SA.checkDotDotExpression(vtype, parts, pi + 2, pcount, sym, i, jcode)
						print "VN", name, SA.ttos(np)
						raise WAFCompileError(-1, "Expecting class,interface , enum ,obejct")
					elif isinstance(np, ExArrayIndex):
						if vtype.coit == None or vtype.coit.clazz != SGlobal.arrayclass:
							raise WAFCompileError(-1, "Not an array")
						code = []
						t = SA.checkExpression(np.exp, sym, i, code)
						if not SA.canBeArrayIndex(t):
							raise WAFCompileError("Can not evalute to positive integer")
						jcode[0] += "[" + code[0] + "]"
						if pi + 2 == pcount:return SA.getTypeWithReducedArray(vtype)
						#TODO:Might need an update here
						return SA.checkDotDotExpression(SA.getTypeWithReducedArray(vtype), parts, pi + 2, pcount, sym, i, jcode)
				elif isinstance(np, ExArguments):
					curClass = SA.currentClass
					#### IE 6
					curType = curClass.mytype
					if curType.coit.clazz.package == "com.openwaf.client.dom" and WAFConfig.isCompatibleWithIE67():
						args = np.arguments
						code = []
						argstl = SA.getExpressionListToTypeList(args, sym, i, code)
						#mapping not required
						cc = curType.coit.clazz
						m = curType.getMethodWithThisAccess(name, argstl, False, None, SA.currentClass)
						if m != None:	
							SA.applyJSTypeCastForArguments(m, argstl, code)					
							if m.method.method.block == None and m.method.method.native_code == None:
								#can not minify this
								jcode[0] += "this." + m.method.getJSName() + "(" + ",".join(code) + ")"								
								if m.method.is_void == True:return None
								rtype = m.rtype
								if pi + 2 == pcount:return rtype
								return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)					
							else:
								if len(jcode[0]) > 0 and jcode[0][-1] == ".":jcode[0] = jcode[0][:-1]
								line = None
								line = cc.getPrototype() + ".$." + m.method.getJSName() + ".call(this"
								if len(code) > 0:
									jcode[0] = line + jcode[0] + "," + ",".join(code) + ")"
								else:
									jcode[0] = line + jcode[0] + ")"
						
								if m.method.is_void == True:return None
								rtype = m.rtype
								if pi + 2 == pcount:return rtype
								return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
						m = curClass.getMethodFromContainerClass(name, argstl, False, SA.currentClass)
						if m == None:
							print "Method not found ", name
							some_method()
						SA.applyJSTypeCastForArguments(m, argstl, code)
						dclazz = m.method.clazz
						d = cc.getDepthRelativeToThis(dclazz)
						if d < 0: some_method()
						if m.method.method.block == None and m.method.method.native_code == None:
							#TODO:not sure about this what exactly is this
							jcode[0] += "this" + ("._pi" * d) + m.method.getJSName() + "(" + ",".join(code) + ")"								
							if m.method.is_void == True:return None
							rtype = m.rtype
							if pi + 2 == pcount:return rtype
							return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)					
						else:
							if len(jcode[0]) > 0 and jcode[0][-1] == ".":jcode[0] = jcode[0][:-1]
							line = None
							line = dclazz.getPrototype() + ".$." + m.method.getJSName() + ".call(this" + ("._pi" * d)
							if len(code) > 0:
								jcode[0] = line + jcode[0] + "," + ",".join(code) + ")"
							else:
								jcode[0] = line + jcode[0] + ")"
					
							if m.method.is_void == True:return None
							rtype = m.rtype
							if pi + 2 == pcount:return rtype
							return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
					###### IE 6
					code = []
					argstl = SA.getExpressionListToTypeList(np.arguments, sym, i, code)
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
					argstl = _argstl
					m = curClass.mytype.getMethodWithThisAccess(name, argstl, False, None, SA.currentClass)
					if m != None:
						if m.method.isStatic():
							jcode[0] += m.method.getDeclaringClass().getPrototype() + ".$" 
						else:
							jcode[0] += "this"
					else:
						m = curClass.getMethodFromContainerClass(name, argstl, False, SA.currentClass)
						if m == None:
							print p.name.lineno, p.name.pos
							print "SA ", SA.currentClass.fullname
							print "curClass", curClass.fullname, curClass.exclass[0].fullname, name
							raise WAFCompileError(1009, p.name)
						if m.method.isStatic():
							jcode[0] += m.method.getDeclaringClass().getPrototype() + ".$"
						else:
							d = SA.currentClass.getDepthRelativeToThis(m.method.clazz)
							jcode[0] += "this" + ("._pi" * d)
					#TODO:J update this based on in which ckass we fint method hint pcl-pc-1
					#jcode[0]+="this."+m.getJSName()+"("+code[0]+")"
					SA.applyJSTypeCastForArguments(m, argstl, code)
					if m.method.isAbstract():
						if WAFConfig.isMinify() == False:
							jcode[0] += "." + m.method.getName() + "_" + str(m.method.mid) + "(" + ",".join(code) + ")"
						else:
							jcode[0] += "." + "_" + str(m.method.mid) + "(" + ",".join(code) + ")"
							
					else:
						jcode[0] += "." + m.method.getJSName() + "(" + ",".join(code) + ")"
					if m.method.is_void == True:return None
					rtype = curClass.mytype.mapAndConvertType(m.rtype, None, SA.currentMethod)
					if pi + 2 == pcount:return rtype
					return SA.checkDotDotExpression(rtype, parts, pi + 2, pcount, sym, i, jcode)
				elif isinstance(np, ExInnerCreator):
					curClass = SA.currentClass
					t = SA.getVariable(name, sym, i)
					creator = np.creator
					if t != None:
						jcode[0] += t.getJSName()
					if t == None:
						t = SA.getFieldFromCurrentClass(name)#update this for static members
						if t.field.isStatic():
							jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
						else:
							jcode[0] += "this." + t.field.getJSName()
					if t == None:
						t = SA.getFieldFromContainerClass(name)
						if t == None:
							raise WAFCompileError(1009, p.name)
						if t.field.isStatic():
							jcode[0] += t.field.getDeclaringClass().getPrototype() + ".$." + t.field.getJSName()
						else:
							d = SA.currentClass.getDepthRelativeToThis(t.field.clazz)
							jcode[0] += "this" + ("._pi" * d) + "." + t.field.getJSName()
					t = SA.getTypeOfVariable(t)
					outerClass = SA.getTypeOfVariable(t).coit.clazz
					innerClass = outerClass.getInnerMember(creator.name.data)
					acode = []
					argstl = SA.getExpressionListToTypeList(creator.classcreator.args, sym, i, acode)		
					_argstl = []
					for _arg in argstl: 
						_argstl.append(curClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
					argstl = _argstl
					cons = innerClass.getConstructor(argstl, SA.currentClass)
					if cons == None:
						print "Constructor not found for inner class"
						print innerClass.getFullname()
						print outerClass.getFullname()
						some_method()
					SA.applyJSTypeCastForArguments(cons, argstl, acode)
					line = None
					#if cons.isDefaultConstructor():
					#	line = "new " + innerClass.getPrototype() + "()"
					#else:
					line = "(new " + innerClass.getPrototype() + "())." + cons.getJSName() + "(" + ",".join(acode) + ")"
					jcode[0] += "._ic" + line 
					return innerClass.mytype
				else:
					print "Not handled"
					some_method()
			
			elif isinstance(p, ExCastExpression):
				#TODO:it me array be carefull not handled right now
				#TODO:check compile time for possible casting of this
				#TODO:J check this
				
				t = SA.checkExpressionArray(p.exp, sym, i, jcode)
				if isinstance(p.typ, PrimitiveType):
					tc = SHelper.getClassOnFullName("com.openwaf.core.framework.TypeCast")
					v = p.typ.value
					if v == PrimitiveType.BYTE:
						jcode[0] = tc.getPrototype() + ".$.rb(" + jcode[0] + ")"
					if v == PrimitiveType.CHAR:
						jcode[0] = tc.getPrototype() + ".$.rc(" + jcode[0] + ")"
					if v == PrimitiveType.INT:
						jcode[0] = tc.getPrototype() + ".$.ri(" + jcode[0] + ")"
					if v == PrimitiveType.SHORT:
						jcode[0] = tc.getPrototype() + ".$.rs(" + jcode[0] + ")"	
					return SGlobal.getBasicTypeForPrimitiveType(p.typ)
				else:
					SHelper.processType(p.typ, SA.currentClass, SA.currentMethod)
					return SA.currentClass.mytype.mapAndConvertType(p.typ, None, SA.currentMethod)

			elif isinstance(p, ExCreator):
				## class creator
				#TODO:J handle this
				c = p.creator
				if c.arraycreator == None:
					code = []
					if SA.currentMethod == None:
						r = SA.processClassCreator(c, sym, i, code, True)
					else:
						r = SA.processClassCreator(c, sym, i, code, False)
					jcode[0] += code[0]
					return r
				else:
					ac = c.arraycreator
					if ac.init == None:
						code = []
						r = SA.processArrayCreator(c.arraycreator, sym, i, code)
						jcode[0] += WAFConfig.getWAFRootObjectName() + ".createArray(" + code[0] + ")"
						return r
					else:
						code = []
						r = SA.processArrayCreator2(c.arraycreator, sym, i, code)
						jcode[0] += code[0]
						return r
			elif isinstance(p, ExLiteral):
				return SA.checkLiteral(p.literal, sym, i, jcode)
			elif isinstance(p, ExParExpression):
				code = []
				r = SA.checkExpression(p.exp, sym, i, code)
				jcode[0] += "(" + code[0] + ")"
				return r
			elif isinstance(p, ExPrimitiveType):
				#TODO:verify this currently ignoring
				#TODO:J check this
				return SGlobal.getBasicTypeForPrimitiveType(p)

			elif isinstance(p, ExSuper):
				#TODO:we need to handle array index here in ExThis is Semantic.py as well
				
				if len(SA.currentClass.exclass) == 0:
					raise WAFCompileError("Class dosent have super class")

				supClass = SA.currentClass.exclass[0]
				np = parts[pi + 1]
				if isinstance(np, ExArguments):#calling super constructor
					jcode[0] += "this"#TODO:i am sure about this
					code = []
					argstl = SA.getExpressionListToTypeList(np.arguments, sym, i, code)
					sc = supClass.getConstructor(argstl, SA.currentClass)
					
					if sc == None:
						raise WAFCompileError(1007, None)
					SA.applyJSTypeCastForArguments(sc, argstl, code)
					jcode[0] += "." + sc.getJSName() + "(" + ",".join(code) + ")"
					pi = pi + 1
					return None
				#this.member....
				elif isinstance(np, ExDot):
					pi = pi + 2
					p = parts[pi]
				
					if pi + 1 == pcount:
						jcode[0] += "this."#TODO:i am sure about this
						f = supClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						jcode[0] += f.field.getJSName()
						return SA.currentClass.mytype.mapAndConvertType(f.type, None, SA.currentMethod)
					np = parts[pi + 1]
					if isinstance(np, ExDot):
						jcode[0] += "this."#TODO:i am sure about this
						f = supClass.getFieldWithThisAccess(p.name.data, False, SA.currentClass)
						if f == None:raise WAFCompileError(1008, p.name)
						jcode[0] += f.field.getJSName()
						r = SA.currentClass.mytype.mapAndConvertType(f.type, None, SA.currentMethod)
						return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
					elif isinstance(np, ExArguments):
						jcode[0] += supClass.getPrototype() + ".$."
						args = np.arguments
						code = []
						argstl = SA.getExpressionListToTypeList(args, sym, i, code)
						_argstl = []
						for _arg in argstl: 
							_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
						argstl = _argstl
						m = supClass.getMethodWithThisAccess(p.name.data, argstl, False, None, SA.currentClass)
						if m == None:
							raise WAFCompileError(1009, p.name.data)
						SA.applyJSTypeCastForArguments(m, argstl, code)
						if m.method.isAbstract():
							if WAFConfig.isMinify() == False:
								jcode[0] += m.method.getName() + "_" + str(m.method.mid) + ".call(this," + ",".join(code) + ")"
							else:
								jcode[0] += "_" + str(m.method.mid) + ".call(this" + ",".join(code) + ")"
						else:
							if len(code) > 0:
								jcode[0] += m.method.getJSName() + ".call(this," + ",".join(code) + ")"
							else:
								jcode[0] += m.method.getJSName() + ".call(this)"
						if m.method.is_void:return None
						r = SA.currentClass.mytype.mapAndConvertType(m.rtype, None, SA.currentMethod)
						if pi + 2 == pcount:return r
						if isinstance(parts[pi + 2], ExDot):
							jcode[0] += "."
							return SA.checkDotDotExpression(r, parts, pi + 3, pcount, sym, i, jcode)
						if isinstance(parts[pi + 2], ExDot):
							return SA.checkDotDotExpression(r, parts, pi + 2, pcount, sym, i, jcode)
						raise WAFCompileError(0, "what is this in method")
				else:
					raise WAFCompileError(-1, "What the hell is this")
					#TODO:
					print "Super not supported"
					some_method()
					return None
					#sys.exit(0)
			elif isinstance(p, ExType):
				#TODO:this should be after the intanceof
				pass
			elif isinstance(p, ExTypeArguments):
				#TODO:ideally this should be ignored just verify it
				pass
			elif isinstance(p, ExVoid):
				#TODO:ideally never be used in code which is goind to be translated to javascript
				pass
				"""
				elif isinstance(p, list):
					line += SA.checkExpressionArray(p, sym, i, jcode)
				"""
			else:
				print "UnExpected:Unknown Expression part ", p
				some_method()
			pi += 1
		return None#TODO:could be error
	@staticmethod
	def processArrayCreator(ac, sym, i, jcode):
		#TODO:process array creator init
		#TODO:j
		line = "["
		add_comm = False
		if ac.exps != None:
			#if ac.arraydim != len(ac.exps):
			#	print "Array initialization not supported"
				##some_method()
			for e in ac.exps:
				if add_comm:line += ","
				code = []
				SA.checkExpression(e, sym, i, code)
				line += "".join(code)
				add_comm = True
		line += "]"
		jcode.append(line)
		t = Type()
		t.arraydim = ac.arraydim

		if isinstance(ac.name, ClassOrInterfaceType):
			t.coit = ac.name
		else:
			t.pm_type = ac.name
		SHelper.processType(t, SA.currentClass, SA.currentMethod)
		return t
	@staticmethod
	def processArrayCreator2(ac, sym, i, jcode):
		#TODO:process array creator init
		#TODO:j
		code = []
		SA.checkArrayInitializer(ac.init, sym, i, code)
		jcode.append("".join(code))
		t = Type()
		t.arraydim = ac.arraydim

		if isinstance(ac.name, ClassOrInterfaceType):
			t.coit = ac.name
		else:
			t.pm_type = ac.name
		SHelper.processType(t, SA.currentClass, SA.currentMethod)
		return t
	@staticmethod
	def checkArrayInitializer(ai, sym, i, jcode):
		line = "["
		add_comma = False
		for vi in ai.part:
			if add_comma == True:line += ","
			code = []
			SA.checkVariableInitializer(vi, sym, i, code)
			line += code[0]
			add_comma = True
		line += "]"
		jcode.append(line)


	@staticmethod
	def processClassCreator(c, sym, i, jcode, static, from_controller=False):
		ccr = c.ccr
		name = SHelper.getCoitNamesToString(c.typ)
		if name == None:
			name = c.typ.fullname
		oclass = SHelper.getClassOnNameFromImported(name, SA.currentClass)
		inner_creation = False
		#if SA.currentClass.isClassInnerToMe(oclass):
		#	innerClass = SA.currentClass.getInnerMember(name)
		#	if innerClass == oclass and oclass.isStatic() == False and oclass.isAbstract() == False:
		#		inner_creation = True
		parent_degree = 0
		if static == False and oclass.isInner() == True and oclass.isStatic() == False and oclass.isAbstract() == False:
			inner_creation = True
			if not SA.currentClass.isClassInnerToMe(oclass):
				cc = SA.currentClass				
				while True:
					parent_degree = parent_degree + 1
					pc = cc.getDeclaringClass()
					if pc != None and isinstance(pc, SMethod):
						pc = pc.clazz.getDeclaringClass()
					if pc == None:
						#raise Exception("Can not found relation to class "+oclass.fullname)
						parent_degree = 0
						break
					if pc.isClassInnerToMe(oclass):
						break		
			
		if oclass == None:
			raise WAFCompileError(1015, c.typ.names[0])#TODO:check this names[0]
		code = []
		argstl = SA.getExpressionListToTypeList(ccr.args, sym, i, code)
		_argstl = []
		for _arg in argstl: 
			_argstl.append(SA.currentClass.mytype.mapAndConvertType(_arg, None, SA.currentMethod))
		argstl = _argstl
	
		cons = None
		if oclass.isClass() or oclass.isEnum():
			cons = oclass.getConstructor(argstl, SA.currentClass)
			if cons == None:
				raise WAFCompileError(1007, c.typ.names[0])#TODO:check this names[0]
		if c.ccr.body == None:
			line = None
			if oclass.fullname == "java.lang.String":
				if isinstance(cons, str) or cons == None:
					line = "\"\""
				else:
					line = SGlobal.stringclass.getPrototype()+".$." + cons.getJSName() + "(" + ",".join(code) + ")"
				jcode.append(line)
				return oclass.mytype
			if inner_creation == False:
				if isinstance(cons, str) or cons == None:
					line = "new " + oclass.getPrototype() + "()"
				else:
					line = "(new " + oclass.getPrototype() + "())." + cons.getJSName() + "(" + ",".join(code) + ")"
			else:
				if isinstance(cons, str) or cons == None:
					line = "this" + (parent_degree * ("._pi")) + "._ic(new " + oclass.getPrototype() + "())"
				else:
					line = "this" + (parent_degree * ("._pi")) + "._ic(new " + oclass.getPrototype() + "())." + cons.getJSName() + "(" + ",".join(code) + ")"
			jcode.append(line)
			return oclass.mytype
		bclass = c.clazz
		ec = ExternCreate()
		ec.from_controller = from_controller
		line = WAFConfig.getWAFRootObjectName() + "._cc.c" + str(ec.cid) + "("
		pargs = []
		if oclass.isClass() or oclass.isEnum():
			if cons == None:
				pargs.append("new " + oclass.getPrototype() + "()")
			else:
				pargs.append("(new " + oclass.getPrototype() + "())." + cons.getJSName() + "(" + ",".join(code) + ")")
		else:
			pargs.append("new " + oclass.getPrototype() + "(" + ",".join(code) + ")")
		ec.clazz = bclass
		outer_class = SA.currentClass
		SA.currentClass = bclass
		o_collect_locals = SA.collect_locals
		SA.collect_locals = True
		o_collect_locals_limit = SA.collect_locals_limit
		SA.collect_locals_limit = i
		o_locals_bag = SA.locals_bag
		SA.locals_bag = {}	
		for m in bclass.methods:
			code = []
			if m.callsModel():
				import Java2js_SCS				
				Java2js_SCS.SCS.checkMethod(m, bclass, sym, i, code)
			else:
				SA.checkMethod(m, bclass, sym, i, code)
			if WAFConfig.isMinify():
				pargs.append(getFormatedCode(code, 0))
			else:
				pargs.append("/* " + m.name + "*/" + getFormatedCode(code, 0))
		
		ec.instances.append(ec)
		SA.currentClass = outer_class
		vnames = SA.locals_bag.keys()
		js_names = []
		SA.collect_locals = False
		for vname in vnames:
			t = SA.getVariable(vname, sym, i)			
			if isinstance(t, SEnum):
				js_names.append(name)
			else:
				js_names.append(t.getJSName())
		scope_args = ",".join(js_names)
		if len(scope_args) > 0:
			if static == False:
				line += "this,(function(" + scope_args + "){return [" + ",".join(pargs) + "]})(" + scope_args + "))"
			else:
				line += "null,(function(" + scope_args + "){return [" + ",".join(pargs) + "]})(" + scope_args + "))"
		else:
			if static == False:
				line += "this,[" + ",".join(pargs) + "])"
			else:
				line += "null,[" + ",".join(pargs) + "])"
		jcode.append(line)
		###
		if o_locals_bag != None:
			names = SA.locals_bag.keys()
			for name in names:
				if SA.locals_bag[name] <= o_collect_locals_limit:
					if not o_locals_bag.has_key(name):
						o_locals_bag[name] = SA.locals_bag[name]
		SA.locals_bag = o_locals_bag
		SA.collect_locals_limit = o_collect_locals_limit
		SA.collect_locals = o_collect_locals
		###		
		return oclass.mytype
		
	
	@staticmethod
	def getVariable(name, sym, i):
		while i >= 0:
			if sym[i].has_key(name):
				if SA.collect_locals == True and i <= SA.collect_locals_limit:
					SA.locals_bag[name] = i
				return sym[i][name]
			i -= 1
		#if SHelper.isEndsWith(SA.currentClass.fullname,"."+ name):
		#	return SA.currentClass
		cls = SHelper.getClassOnNameFromImported(name, SA.currentClass)
		if cls != None:
			return cls
		return None
		#print name
		#raise WAFCompileError(-1, "Identifier not found")
	@staticmethod
	def getTypeOfVariable(v):
		if isinstance(v, Type):
			return v
		if isinstance(v, Parameter):
			return SA.getTypeOfVariable(v.typ)
		if isinstance(v, ExField):
			return SA.getTypeOfVariable(v.type)
		if isinstance(v, SField):
			return SA.getTypeOfVariable(v.type)
		if isinstance(v, SEnum):
			return v.mytype
		if isinstance(v, SClass):
			return v.mytype
		if isinstance(v, SInterface):
			return v.mytype
		if isinstance(v, VariableDeclarator):
			return SA.getTypeOfVariable(v.typ)
		if isinstance(v, TypeParameter):
			if v.bound != None:
				return SA.getTypeOfVariable(v.bound[0])
			return SGlobal.objclass.mytype
			
		print SA.ttos(v)
		raise WAFCompileError(-1, "invalid argument passed to ge the type")

	@staticmethod
	def checkLiteral(l, sym, i, jcode):#TODO
		#TODO:J
		jcode[0] += l.toJS()
		return SGlobal.getBasicTypeForLiteral(l)
		"""
				if l.typ in [Literal.STRING, Literal.FLOAT, Literal.CHAR, Literal.INT, Literal.LONG]:
						return l.value
				if l.typ == Literal.TRUE:return "true"
				if l.typ == Literal.FALSE:return "false"
				if l.typ == Literal.NULL:return "null"

				print "unexpected literal type"
				sys.exit(0)
				"""

	@staticmethod
	def checkOperator(o, sym, i):#complete
		if o >= OprAssign.NORMAL and o <= OprAssign.RIGHT_RIGHT_SHIFT:
			if o == OprAssign.AND:			return "&="
			if o == OprAssign.DIVIDE:		 return  "/="
			if o == OprAssign.LEFT_SHIFT:		 return  "<<="
			if o == OprAssign.MINUS:		  return  "-="
			if o == OprAssign.MOD:			return  "%="
			if o == OprAssign.MULTIPLY:		   return  "*="
			if o == OprAssign.NORMAL:		 return  "="
			if o == OprAssign.OR:			 return  "|="
			if o == OprAssign.PLUS:		   return  "+="
			if o == OprAssign.RIGHT_RIGHT_SHIFT:	  return  ">>>="
			if o == OprAssign.RIGHT_SHIFT:		return  ">>="
			if o == OprAssign.XOR:			return  "^="
		if o >= OprBinary.AND and o <= OprBinary.XOR:
			if o == OprBinary.AND:	return "&"
			if o == OprBinary.OR:	 return "|"
			if o == OprBinary.XOR:	return "^"
		if o >= OprLogical.AND and o <= OprLogical.OR:
			if o == OprLogical.AND:   return "&&"
			if o == OprLogical.OR:	return "||"
		if o >= OprRelational.GT and o <= OprRelational.LTE:
			if o == OprRelational.GT: return ">"
			if o == OprRelational.GTE:return ">="
			if o == OprRelational.LT: return "<"
			if o == OprRelational.LTE:return "<="
		if o >= OprEquality.ET and o <= OprEquality.NET:
			if o == OprEquality.ET:   return "=="
			if o == OprEquality.NET:  return "!="
		if o >= OprShift.LEFT_SHIFT and o <= OprShift.RIGHT_RIGHT_SHIFT:
			if o == OprShift.LEFT_SHIFT:	  return "<<"
			if o == OprShift.RIGHT_SHIFT:	 return ">>"
			if o == OprShift.RIGHT_RIGHT_SHIFT:return ">>>"
		if o >= OprTernary.IF and o <= OprTernary.ELSE:
			if o == OprTernary.IF:	return "?"
			if o == OprTernary.ELSE:  return ":"
		if o >= OprAdditive.PLUS and o <= OprAdditive.MINUS:
			if o == OprAdditive.PLUS: return "+"
			if o == OprAdditive.MINUS:return "-"
		if o >= OprMultiplicative.MULTIPY and o <= OprMultiplicative.MOD:
			if o == OprMultiplicative.DIVIDE: return "/"
			if o == OprMultiplicative.MOD:	return "%"
			if o == OprMultiplicative.MULTIPY:return "*"
		if o >= OprUnary.INC and o <= OprUnary.TILDE:
			if o == OprUnary.DEC:return "--"
			if o == OprUnary.INC:return "++"
			if o == OprUnary.NEGATIVE:return "-"
			if o == OprUnary.NOT:return "!"
			if o == OprUnary.TILDE:return "~"
			if o == OprUnary.POSITIVE:return "+"
		if o >= OprPostfix.INC and o <= OprPostfix.DEC:
			if o == OprPostfix.INC:return "++"
			if o == OprPostfix.DEC:return "--"
		if o == OprInstanceOf.INSTANCEOF:
			return " instanceof "#spaces are necessory here
		print "Fatal Error: could not found operator"


